diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index 9e0f6560b..2fc0d1455 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 @@ -54,11 +56,13 @@ bics BISR BODIEN BODSTS +brealid BRGR brhi brne bswtrg BSWTRG +Bytesto CANEN CANRX CANTX @@ -73,6 +77,7 @@ CCNT CCNTR CCPN CCPR +CCRH CDTY CDTYR CFBS @@ -84,21 +89,26 @@ CHSR CICR CISR CKDIV +CKDIVMD CKEY CKGR CKLO CKPS CLDIV +CLEARINTENA CLKA CLKB +CLKDIS CLKEN clki CLKI CLKP CLKS +CLKSOURCE CLKSTA CLRB CLRF +clrm CLRPSW CMCNT CMCON @@ -120,6 +130,8 @@ CODR comms COMPA CONFG +coreid +coremqtt CORTUS coverity Coverity @@ -143,6 +155,7 @@ CPRE cpsid cpsie CPSR +CPUCLK CPUID CRCB crflash @@ -152,11 +165,14 @@ crhook croutine CRTV CSAAT +CSDK csrr csrs csrw CTCR ctest +CTPC +CTPSW CTRLA CTSIC CUPD @@ -174,11 +190,15 @@ DATNB DATRDY DBGU DCDIC +DCMOCK DCMR Dconfig DCOUNT decf decfsz +decihours +Decihours +DECIHOURS DECNT DFPU DFREERTOS @@ -216,6 +236,7 @@ DTREN DTXD DUNITY DVAR +Dxxx EABI ecall ECIT @@ -226,6 +247,7 @@ EEVT eevtedg EEVTEDG EFRHD +EIIC EINT EIPC EIPSW @@ -278,6 +300,7 @@ FADD FCMD fcolor FCSE +fcsr fdiagnostics fdiv FDIV @@ -299,6 +322,7 @@ FNTR FOSC FPCCR FPCSR +FPEPC FPSW FPUL FRDY @@ -311,6 +335,7 @@ FSR fwait GCACC GCTRL +getpacketid getvect GIEH GIEL @@ -326,6 +351,7 @@ GPTA HCLK Hitach HRESP +HTCFG HWHSH HWORD HWRD @@ -341,6 +367,7 @@ ICCR ICCRPR ICCRX ICERST +ICIPI ICSR IDCR IECR @@ -360,6 +387,7 @@ INTTM IODEFINE IORLW IPEN +IPIR IPLB ipsr IPSR @@ -368,9 +396,10 @@ IRET IRXFCS ISRAM ISRR -ISR's ISRS +ISR's ISRTICK +isystem ITIF ITMC ITMK @@ -401,6 +430,7 @@ ldrbs LDRBS LDRNE ldsr +ldxr lidt LINKR LJMP @@ -423,6 +453,7 @@ MAINRDY MAIR Mang Mbits +mbranch mcause MCFR MCKA @@ -475,6 +506,7 @@ movs movw MOVWF movx +MPIDR MPLAB MPUCTRL MQTT @@ -513,6 +545,7 @@ MVTACHI MVTACLO MVTC MVTIPL +mypy NCFGR NCPHA NEBP @@ -522,6 +555,9 @@ NIOSII NIRQ NOGIC noheap +nondet +Nondet +NONDET nostdint NPCS NRSTL @@ -532,6 +568,10 @@ NTRST NVIC ODAT ODSR +OINC +OIWBNOWA +OIWBWA +OIWTNOWA OPMOD optimisations OPTIMISED @@ -543,6 +583,7 @@ OSCEN OSCOFF OSCOUNT OSMC +OSTM outpw OVLY OVRE @@ -552,6 +593,8 @@ OWATCOM OWDR OWER OWSR +pacbti +PACBTI PAGEN PCDR PCER @@ -563,6 +606,7 @@ PCLKSEL PCSR PCXI PDSR +PEID PEIE PENDSV PENDSVCLEAR @@ -613,6 +657,7 @@ PREB PRIA Prioritised PRIS +PRIVDEFENA PROCDLY PRODH PRODL @@ -635,7 +680,11 @@ PUSHNE PUSHW pushx PWMC +pylint +pytest +pyyaml RAMPZ +randomisation RASR Rationalised Raynald @@ -690,6 +739,7 @@ Rsvd RTAR RTCEN RTCSC +RTICTL RTIE RTIF RTIFRC @@ -713,6 +763,7 @@ RXRSM RXSETUP RXSUSP RXSYN +RXTDIS RXTEN RXUBR SBYCR @@ -726,9 +777,11 @@ SECU SENDA SETB SETEN +SETINTENA SETPSW SETR setvect +sevl SFRC SHLL SHLR @@ -736,6 +789,7 @@ SHPR SHTIM SIFIVE sinclude +slli SODR SOFTIRQ SPCK @@ -758,6 +812,7 @@ STTBRK STTDLY STTOUT STTTO +stxr SVACC svcne SVDIS @@ -771,7 +826,18 @@ SWINTR SWRST SWTRG synchronise +SYNCM +syncm SYSC +sysclk +Sysclk +SysClk +SYSClk +SYSCLK +sysclock +Sysclock +SysClock +SYSCLOCK TACCR TACCTL TACLR @@ -847,10 +913,23 @@ TXTEN TXUBR TXVC TXVDIS +UBTI UDCP +UNACKED uncrustify +UNDADD +unpadded +Unpadded +UNPADDED +unprotect +Unprotect +Unprotected UNRE +UNSUB +UNSUBACK +unsubscriptions unsuspended +UPAC URAD URAT URSTEN @@ -863,14 +942,18 @@ USRIO utest utilises utilising +vcsr VDDCORE vect +Vect VECT VECTACTIVE +VECTKEY visualisation vldmdbeq vldmia vldmiaeq +vlenb VMSRNE vpop VPOPNE @@ -878,6 +961,7 @@ vpush VPUSHNE VRPM Vrtc +vsetvl vstmdbeq vstmiaeq VTOR diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 48fe891ac..771aee37d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,7 +4,7 @@ # the repo. Unless a later match takes precedence, # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. -* @FreeRTOS/pr-bar-raiser +* @FreeRTOS/pr-bar-raisers # Order is important; the last matching pattern takes the most # precedence. When someone opens a pull request that only diff --git a/.github/allowed_urls.txt b/.github/allowed_urls.txt new file mode 100644 index 000000000..578b90e3d --- /dev/null +++ b/.github/allowed_urls.txt @@ -0,0 +1,3 @@ +https://www.renesas.com/us/en/document/mah/rh850f1k-group-users-manual-hardware?r=1170166 +https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rh850-automotive-mcus +https://www.renesas.com/us/en/software-tool/c-compiler-package-rh850-family#downloads diff --git a/.github/scripts/kernel_checker.py b/.github/scripts/kernel_checker.py index 0e8556350..f442a2ccd 100755 --- a/.github/scripts/kernel_checker.py +++ b/.github/scripts/kernel_checker.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 #/* # * FreeRTOS Kernel -# * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. # * # * SPDX-License-Identifier: MIT # * @@ -28,6 +28,7 @@ # */ import os +import re from common.header_checker import HeaderChecker #-------------------------------------------------------------------------------------------------- @@ -37,7 +38,8 @@ KERNEL_IGNORED_FILES = [ 'FreeRTOS-openocd.c', 'Makefile', '.DS_Store', - 'cspell.config.yaml' + 'cspell.config.yaml', + '.clang-format' ] KERNEL_IGNORED_EXTENSIONS = [ @@ -105,10 +107,24 @@ KERNEL_THIRD_PARTY_PATTERNS = [ r'.*portable/GCC/AVR32_UC3/.*', ] +KERNEL_ARM_COLLAB_FILES_PATTERNS = [ + r'.*portable/ARMv8M/*', + r'.*portable/.*/ARM_CM23*', + r'.*portable/.*/ARM_CM33*', + 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*', + r'.*portable/.*/ARM_CR82*', +] + KERNEL_HEADER = [ '/*\n', ' * FreeRTOS Kernel \n', - ' * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n', + ' * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n', ' *\n', ' * SPDX-License-Identifier: MIT\n', ' *\n', @@ -135,18 +151,95 @@ KERNEL_HEADER = [ ' */\n', ] + +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(-20\d\d)? Arm Limited and/or its affiliates( +)?( \*\/)?$)|" + \ + r"(^(;|#)?( *(\/\*|\*|#|\/\/))? ( \*\/)?$)" + + +class KernelHeaderChecker(HeaderChecker): + def __init__( + self, + header, + padding=1000, + ignored_files=None, + ignored_ext=None, + ignored_patterns=None, + py_ext=None, + asm_ext=None, + third_party_patterns=None, + copyright_regex = None + ): + super().__init__(header, padding, ignored_files, ignored_ext, ignored_patterns, + py_ext, asm_ext, third_party_patterns, copyright_regex) + + self.armCollabRegex = re.compile(FREERTOS_ARM_COLLAB_COPYRIGHT_REGEX) + + self.armCollabFilesPatternList = [] + for pattern in KERNEL_ARM_COLLAB_FILES_PATTERNS: + self.armCollabFilesPatternList.append(re.compile(pattern)) + + def isArmCollabFile(self, path): + for pattern in self.armCollabFilesPatternList: + if pattern.match(path): + return True + return False + + def checkArmCollabFile(self, path): + isValid = False + file_ext = os.path.splitext(path)[-1] + + with open(path, encoding="utf-8", errors="ignore") as file: + chunk = file.read(len("".join(self.header)) + self.padding) + lines = [("%s\n" % line) for line in chunk.strip().splitlines()][ + : len(self.header) + 2 + ] + if (len(lines) > 0) and (lines[0].find("#!") == 0): + lines.remove(lines[0]) + + # Split lines in sections. + headers = dict() + headers["text"] = [] + headers["copyright"] = [] + headers["spdx"] = [] + for line in lines: + if self.armCollabRegex.match(line): + headers["copyright"].append(line) + elif "SPDX-License-Identifier:" in line: + headers["spdx"].append(line) + else: + headers["text"].append(line) + + text_equal = self.isValidHeaderSection(file_ext, "text", headers["text"]) + spdx_equal = self.isValidHeaderSection(file_ext, "spdx", headers["spdx"]) + + if text_equal and spdx_equal and len(headers["copyright"]) == 3: + isValid = True + + return isValid + + def customCheck(self, path): + isValid = False + if self.isArmCollabFile(path): + isValid = self.checkArmCollabFile(path) + return isValid + + def main(): parser = HeaderChecker.configArgParser() args = parser.parse_args() # Configure the checks then run - checker = HeaderChecker(KERNEL_HEADER, - ignored_files=KERNEL_IGNORED_FILES, - ignored_ext=KERNEL_IGNORED_EXTENSIONS, - ignored_patterns=KERNEL_IGNORED_PATTERNS, - third_party_patterns=KERNEL_THIRD_PARTY_PATTERNS, - py_ext=KERNEL_PY_EXTENSIONS, - asm_ext=KERNEL_ASM_EXTENSIONS) + checker = KernelHeaderChecker(KERNEL_HEADER, + copyright_regex=FREERTOS_COPYRIGHT_REGEX, + ignored_files=KERNEL_IGNORED_FILES, + ignored_ext=KERNEL_IGNORED_EXTENSIONS, + ignored_patterns=KERNEL_IGNORED_PATTERNS, + third_party_patterns=KERNEL_THIRD_PARTY_PATTERNS, + py_ext=KERNEL_PY_EXTENSIONS, + asm_ext=KERNEL_ASM_EXTENSIONS) checker.ignoreFile(os.path.split(__file__)[-1]) rc = checker.processArgs(args) diff --git a/.github/scripts/manifest_updater.py b/.github/scripts/manifest_updater.py index 684c7cb5a..fc2343da3 100755 --- a/.github/scripts/manifest_updater.py +++ b/.github/scripts/manifest_updater.py @@ -11,7 +11,7 @@ def update_manifest_file(new_version_number): for line in f: line = line.strip() if line.startswith('version'): - updated_lines.append(f'version: "v{new_version_number}"\n') + updated_lines.append(f'version: "V{new_version_number}"\n') else: updated_lines.append(f'{line}\n') diff --git a/.github/third_party_tools.md b/.github/third_party_tools.md new file mode 100644 index 000000000..09bd6d62c --- /dev/null +++ b/.github/third_party_tools.md @@ -0,0 +1,14 @@ +Note that these tools are provided by different vendors and not by the FreeRTOS +team. + +## Tracing Tools +| Tool | Website | Getting Started | +|------|---------|-----------------| +| Tracelyzer | [Link](https://percepio.com/tracealyzer/freertostrace/) | [Link](https://percepio.com/getstarted/latest/html/freertos.html) | +| SystemView | [Link](https://www.segger.com/products/development-tools/systemview/) | [Link](https://wiki.segger.com/FreeRTOS_with_SystemView) | + +## Static Code Analysis Tools +| Tool | Website | Getting Started | +|------|---------|-----------------| +| Code Sonar | [Link](https://codesecure.com/our-products/codesonar/) | [Link](https://github.com/CodeSecure-SE/FreeRTOS-Kernel/blob/main/examples/codesonar/README.md) | +| Coverity | [Link](https://www.blackduck.com/static-analysis-tools-sast/coverity.html) | [Link](../examples/coverity/README.md) | diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 73ec92cf0..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: @@ -31,50 +33,62 @@ jobs: # Currently FreeRTOS/.github/scripts houses the release script. Download it for upcoming usage - name: Checkout FreeRTOS Release Tools - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: repository: FreeRTOS/FreeRTOS path: tools # Simpler git auth if we use checkout action and forward the repo to release script - name: Checkout FreeRTOS Kernel - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: local_kernel fetch-depth: 0 - name: Configure git identity + env: + ACTOR: ${{ github.actor }} run: | - git config --global user.name ${{ github.actor }} - git config --global user.email ${{ github.actor }}@users.noreply.github.com + git config --global user.name "$ACTOR" + git config --global user.email "$ACTOR"@users.noreply.github.com - name: create a new branch that references commit id + env: + VERSION_NUMBER: ${{ github.event.inputs.version_number }} + COMMIT_ID: ${{ github.event.inputs.commit_id }} working-directory: ./local_kernel run: | - git checkout -b ${{ github.event.inputs.version_number }} ${{ github.event.inputs.commit_id }} + git checkout -b "$VERSION_NUMBER" "$COMMIT_ID" echo "COMMIT_SHA_1=$(git rev-parse HEAD)" >> $GITHUB_ENV - name: Update source files with version info + env: + VERSION_NUMBER: ${{ github.event.inputs.version_number }} + MAIN_BR_VERSION_NUMBER: ${{ github.event.inputs.main_br_version }} + COMMIT_SHA_1: ${{ env.COMMIT_SHA_1 }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Install deps and run pip install -r ./tools/.github/scripts/release-requirements.txt - ./tools/.github/scripts/update_src_version.py FreeRTOS --kernel-repo-path=local_kernel --kernel-commit=${{ env.COMMIT_SHA_1 }} --new-kernel-version=${{ github.event.inputs.version_number }} --new-kernel-main-br-version=${{ github.event.inputs.main_br_version }} + ./tools/.github/scripts/update_src_version.py FreeRTOS --kernel-repo-path=local_kernel --kernel-commit="$COMMIT_SHA_1" --new-kernel-version="$VERSION_NUMBER" --new-kernel-main-br-version="$MAIN_BR_VERSION_NUMBER" exit $? - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name : Update version number in manifest.yml + env: + VERSION_NUMBER: ${{ github.event.inputs.version_number }} working-directory: ./local_kernel run: | - ./.github/scripts/manifest_updater.py -v ${{ github.event.inputs.version_number }} + ./.github/scripts/manifest_updater.py -v "$VERSION_NUMBER" exit $? - name : Commit version number change in manifest.yml + env: + VERSION_NUMBER: ${{ github.event.inputs.version_number }} working-directory: ./local_kernel run: | git add . git commit -m '[AUTO][RELEASE]: Update version number in manifest.yml' - git push -u origin ${{ github.event.inputs.version_number }} + git push -u origin "$VERSION_NUMBER" - name: Generate SBOM uses: FreeRTOS/CI-CD-Github-Actions/sbom-generator@main @@ -83,24 +97,40 @@ jobs: source_path: ./ - name: commit SBOM file + env: + VERSION_NUMBER: ${{ github.event.inputs.version_number }} working-directory: ./local_kernel run: | git add . git commit -m '[AUTO][RELEASE]: Update SBOM' - git push -u origin ${{ github.event.inputs.version_number }} + git push -u origin "$VERSION_NUMBER" echo "COMMIT_SHA_2=$(git rev-parse HEAD)" >> $GITHUB_ENV - name: Release + env: + VERSION_NUMBER: ${{ github.event.inputs.version_number }} + MAIN_BR_VERSION_NUMBER: ${{ github.event.inputs.main_br_version }} + COMMIT_SHA_2: ${{ env.COMMIT_SHA_2 }} + REPO_OWNER: ${{ github.repository_owner }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Install deps and run pip install -r ./tools/.github/scripts/release-requirements.txt - ./tools/.github/scripts/release.py ${{ github.repository_owner }} --kernel-repo-path=local_kernel --kernel-commit=${{ env.COMMIT_SHA_2 }} --new-kernel-version=${{ github.event.inputs.version_number }} --new-kernel-main-br-version=${{ github.event.inputs.main_br_version }} + ./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 $? - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - 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 }} working-directory: ./local_kernel run: | # Delete the branch created for Tag by SBOM generator - git push -u origin --delete ${{ github.event.inputs.version_number }} + git push -u origin --delete "$VERSION_NUMBER" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc6d8802b..2765466be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,9 +7,9 @@ on: workflow_dispatch: jobs: formatting: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.1 - name: Check Formatting of FreeRTOS-Kernel Files uses: FreeRTOS/CI-CD-Github-Actions/formatting@main with: @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone This Repo - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 - name: Run spellings check uses: FreeRTOS/CI-CD-Github-Actions/spellings@main with: @@ -30,14 +30,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone This Repo - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 - name: Link Verification uses: FreeRTOS/CI-CD-Github-Actions/link-verifier@main + with: + allowlist-file: '.github/allowed_urls.txt' verify-manifest: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.1 with: submodules: true fetch-depth: 0 diff --git a/.github/workflows/coverity_scan.yml b/.github/workflows/coverity_scan.yml index 85db51800..0afc8e2e1 100644 --- a/.github/workflows/coverity_scan.yml +++ b/.github/workflows/coverity_scan.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 - env: stepName: Install Build Essentials @@ -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 @@ -86,3 +97,42 @@ jobs: echo "::endgroup::" echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " echo "${COV_SCAN_UPLOAD_STATUS}" | grep -q -e 'Build successfully submitted' || echo >&2 "Error submitting build for analysis: ${COV_SCAN_UPLOAD_STATUS}" + + - env: + stepName: Coverity Build for SMP FreeRTOS + COVERITY_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} + COVERITY_EMAIL: ${{ secrets.COVERITY_SCAN_EMAIL }} + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + + export PATH="$PATH:${{env.cov_scan_path}}" + cmake -S ./examples/cmake_example/ -B build -DFREERTOS_SMP_EXAMPLE=1 + cd build + cov-build --dir cov-int make -j + # Move the report out of the build directory + tar czvf ../gcc_freertos_kernel_smp_sample_build.tgz cov-int + + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " + + - env: + stepName: Upload FreeRTOS SMP Coverity Report for Scan + COVERITY_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} + COVERITY_EMAIL: ${{ secrets.COVERITY_SCAN_EMAIL }} + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + + COV_SCAN_UPLOAD_STATUS=$(curl --form token=${COVERITY_TOKEN} \ + --form email=${COVERITY_EMAIL} \ + --form file=@gcc_freertos_kernel_smp_sample_build.tgz \ + --form version="Mainline" \ + --form description="FreeRTOS Kernel SMP Commit Scan" \ + https://scan.coverity.com/builds?project=FreeRTOS-Kernel) + + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " + echo "${COV_SCAN_UPLOAD_STATUS}" | grep -q -e 'Build successfully submitted' || echo >&2 "Error submitting build for analysis: ${COV_SCAN_UPLOAD_STATUS}" diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml deleted file mode 100644 index 14d41c9c0..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/git-secrets.yml b/.github/workflows/git-secrets.yml index 2b88ce0a7..81b929cd3 100644 --- a/.github/workflows/git-secrets.yml +++ b/.github/workflows/git-secrets.yml @@ -7,11 +7,11 @@ jobs: git-secrets: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.1 with: submodules: recursive - name: Checkout awslabs/git-secrets - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: repository: awslabs/git-secrets ref: master diff --git a/.github/workflows/kernel-checks.yml b/.github/workflows/kernel-checks.yml index cfaec5b12..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 @@ -15,7 +15,7 @@ jobs: # There is shared code, hosted by FreeRTOS/FreeRTOS, with deps needed by header checker - name: Checkout FreeRTOS Tools - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: repository: FreeRTOS/FreeRTOS sparse-checkout: '.github' @@ -24,7 +24,7 @@ jobs: # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: inspect diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml index bae32c966..9371e9cea 100644 --- a/.github/workflows/kernel-demos.yml +++ b/.github/workflows/kernel-demos.yml @@ -1,13 +1,20 @@ name: FreeRTOS-Kernel Demos on: [push, pull_request] +env: + # The bash escape character is \033 + bashPass: \033[32;1mPASSED - + bashInfo: \033[33;1mINFO - + bashFail: \033[31;1mFAILED - + bashEnd: \033[0m + jobs: WIN32-MSVC: name: WIN32 MSVC runs-on: windows-latest steps: - name: Checkout the FreeRTOS/FreeRTOS Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: ref: main repository: FreeRTOS/FreeRTOS @@ -16,7 +23,7 @@ jobs: # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: ./FreeRTOS/Source @@ -36,7 +43,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout the FreeRTOS/FreeRTOS Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: ref: main repository: FreeRTOS/FreeRTOS @@ -45,7 +52,7 @@ jobs: # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: ./FreeRTOS/Source @@ -58,10 +65,16 @@ jobs: POSIX-GCC: name: Native GCC - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: + - macos-latest + - ubuntu-latest + runs-on: ${{ matrix.os }} steps: - name: Checkout the FreeRTOS/FreeRTOS Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: ref: main repository: FreeRTOS/FreeRTOS @@ -70,12 +83,13 @@ jobs: # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: ./FreeRTOS/Source - name: Install GCC shell: bash + if: matrix.os == 'ubuntu-latest' run: | sudo apt-get -y update sudo apt-get -y install build-essential @@ -96,7 +110,7 @@ jobs: steps: # Checkout user pull request changes - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 - name: Install GCC shell: bash @@ -123,7 +137,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the FreeRTOS/FreeRTOS Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: ref: main repository: FreeRTOS/FreeRTOS @@ -132,49 +146,154 @@ jobs: # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: ./FreeRTOS/Source - - name: Install MSP430 Toolchain + - env: + stepName: Install MSP430 Toolchain shell: bash run: | - sudo apt-get -y update - sudo apt-get -y install gcc-msp430 build-essential + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + sudo apt update -y + sudo apt install -y p7zip-full + 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 working-directory: FreeRTOS/Demo/msp430_GCC - run: make -j + run: make -j CC=/usr/bin/msp430-gcc/bin/msp430-elf-gcc OPT="-Os -I/usr/bin/msp430-gcc/include -L/usr/bin/msp430-gcc/include" + + MicroBlaze-GCC: + name: GCC MicroBlaze Toolchain + runs-on: ubuntu-latest + steps: + - name: Checkout the FreeRTOS/FreeRTOS Repository + uses: actions/checkout@v4.1.1 + with: + ref: main + repository: FreeRTOS/FreeRTOS + fetch-depth: 1 + + - env: + stepName: Fetch Community-Supported-Demos Submodule + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos + # This repository contains the microblaze_instructions.h header file + git clone https://github.com/Xilinx/embeddedsw.git --branch xilinx_v2023.1 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + + # Checkout user pull request changes + - name: Checkout Pull Request + uses: actions/checkout@v4.1.1 + with: + path: ./FreeRTOS/Source + + - env: + stepName: Install Dependancies + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + sudo apt update -y + sudo apt upgrade -y + sudo apt install -y build-essential m4 debhelper bison texinfo dejagnu flex + 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 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 $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 + mb-gcc --version + + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + + - env: + stepName: Compile Microblaze Port + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + # Compile MicroBlazeV9 Port files to validate they build + mb-gcc -mcpu=v9.5 -c \ + FreeRTOS/Source/portable/GCC/MicroBlazeV9/port.c \ + FreeRTOS/Source/portable/GCC/MicroBlazeV9/portasm.S \ + FreeRTOS/Source/portable/GCC/MicroBlazeV9/port_exceptions.c \ + FreeRTOS/Source/tasks.c \ + FreeRTOS/Source/list.c \ + -I embeddedsw/lib/bsp/standalone/src/microblaze \ + -I FreeRTOS/Source/portable/GCC/MicroBlazeV9/ \ + -I FreeRTOS/Source/include \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/RTOSDemo/src \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/standalone_v5_4/src \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/include \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/intc_v3_5/src + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + ARM-GCC: name: GNU ARM Toolchain runs-on: ubuntu-latest steps: - name: Checkout the FreeRTOS/FreeRTOS Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: ref: main repository: FreeRTOS/FreeRTOS fetch-depth: 1 - - name: Fetch Community-Supported-Demos Submodule + - env: + stepName: Fetch Dependencies shell: bash run: | - # Fetch Community-Supported-Demos Submodule - echo "::group::Fetch Community-Supported-Demos Submodule" - git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos - echo "::engdroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mCloned the Community-Supported-Demos\033[0m" - else - echo -e "\033[32;31mCommunity-Supported-Demos Clone Failed...\033[0m" - exit 1 - fi + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: ./FreeRTOS/Source @@ -189,6 +308,16 @@ jobs: working-directory: FreeRTOS/Demo/CORTEX_MPU_M3_MPS2_QEMU_GCC run: make -j + - name: Build CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_MPU_R4F_TI_RM46_HERCULES_GCC + run: cmake -S . -B build && make -j -C build all + + - name: Build CORTEX_MPU_R5F_TI_RM57_HERCULES_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_MPU_R5F_TI_RM57_HERCULES_GCC + run: cmake -S . -B build && make -j -C build all + - name: Build CORTEX_LM3S102_GCC Demo shell: bash working-directory: FreeRTOS/Demo/CORTEX_LM3S102_GCC diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index c154750b4..bc8aaf69c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -3,10 +3,10 @@ on: [push, pull_request] jobs: run: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout Parent Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: ref: main repository: FreeRTOS/FreeRTOS @@ -15,7 +15,7 @@ jobs: # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 with: path: ./FreeRTOS/Source @@ -45,12 +45,12 @@ jobs: fail_ci_if_error: false verbose: false - name: Archive code coverage data - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: coverage-data path: FreeRTOS/Test/CMock/build/cmock_test* - name: Archive code coverage html report - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: coverage-report path: FreeRTOS/Test/CMock/build/coverage diff --git a/CMakeLists.txt b/CMakeLists.txt index 5323ec19b..f6007d07f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,9 @@ if(NOT FREERTOS_PORT) " GCC_ARM_CM85_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M85 non-trustzone non-secure\n" " GCC_ARM_CM85_TFM - Compiler: GCC Target: ARM Cortex-M85 non-secure for TF-M\n" " GCC_ARM_CR5 - Compiler: GCC Target: ARM Cortex-R5\n" + " GCC_ARM_CRX_MPU - Compiler: GCC Target: ARM Cortex-Rx with MPU\n" " GCC_ARM_CRX_NOGIC - Compiler: GCC Target: ARM Cortex-Rx no GIC\n" + " GCC_ARM_CR82 - Compiler: GCC Target: ARM Cortex-R82\n" " GCC_ARM7_AT91FR40008 - Compiler: GCC Target: ARM7 Atmel AT91R40008\n" " GCC_ARM7_AT91SAM7S - Compiler: GCC Target: ARM7 Atmel AT91SAM7S\n" " GCC_ARM7_LPC2000 - Compiler: GCC Target: ARM7 LPC2000\n" @@ -137,15 +139,18 @@ if(NOT FREERTOS_PORT) " IAR_ARM_CM33_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-secure\n" " IAR_ARM_CM33_SECURE - Compiler: IAR Target: ARM Cortex-M33 secure\n" " IAR_ARM_CM33_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-trustzone non-secure\n" + " IAR_ARM_CM33_TFM - Compiler: IAR Target: ARM Cortex-M33 non-secure for TF-M\n" " IAR_ARM_CM35P_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-secure\n" " IAR_ARM_CM35P_SECURE - Compiler: IAR Target: ARM Cortex-M35P secure\n" " IAR_ARM_CM35P_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-trustzone non-secure\n" " IAR_ARM_CM55_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-secure\n" " IAR_ARM_CM55_SECURE - Compiler: IAR Target: ARM Cortex-M55 secure\n" " IAR_ARM_CM55_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n" + " IAR_ARM_CM55_TFM - Compiler: IAR Target: ARM Cortex-M55 non-secure for TF-M\n" " IAR_ARM_CM85_NONSECURE - Compiler: IAR Target: ARM Cortex-M85 non-secure\n" " IAR_ARM_CM85_SECURE - Compiler: IAR Target: ARM Cortex-M85 secure\n" " IAR_ARM_CM85_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M85 non-trustzone non-secure\n" + " IAR_ARM_CM85_TFM - Compiler: IAR Target: ARM Cortex-M85 non-secure for TF-M\n" " IAR_ARM_CRX_NOGIC - Compiler: IAR Target: ARM Cortex-Rx no GIC\n" " IAR_ATMEGA323 - Compiler: IAR Target: ATMega323\n" " IAR_ATMEL_SAM7S64 - Compiler: IAR Target: Atmel SAM7S64\n" @@ -217,16 +222,17 @@ elseif((FREERTOS_PORT STREQUAL "A_CUSTOM_PORT") AND (NOT TARGET freertos_kernel_ " port.c\n" " portmacro.h\n" " Where FreeRTOSCustomPort/CMakeLists.txt is a modified version of:\n" - " add_library(freertos_kernel_port STATIC)\n" + " add_library(freertos_kernel_port OBJECT)\n" " target_sources(freertos_kernel_port\n" " PRIVATE\n" " port.c\n" " portmacro.h)\n" - " target_include_directories(freertos_kernel_port\n" - " PUBLIC\n" + " add_library(freertos_kernel_port_headers INTERFACE)\n" + " target_include_directories(freertos_kernel_port_headers INTERFACE \n" " .)\n" " target_link_libraries(freertos_kernel_port\n" " PRIVATE\n" + " freertos_kernel_port_headers\n" " freertos_kernel_include)") endif() @@ -257,8 +263,11 @@ endif() target_link_libraries(freertos_kernel PUBLIC - freertos_kernel_port freertos_kernel_include + freertos_kernel_port_headers + PRIVATE + freertos_kernel_port + ) ######################################################################## diff --git a/History.txt b/History.txt index a8e5ac7ba..7df76e16f 100644 --- a/History.txt +++ b/History.txt @@ -1,5 +1,217 @@ Documentation and download available at https://www.FreeRTOS.org/ +Changes between FreeRTOS V11.1.0 and FreeRTOS V11.2.0 released March 04, 2025 + + + Add CC-RH port for Renesas F1Kx devices. We thank @TrongNguyenR for their + contribution. + + Add Pointer Authentication (PAC) and Branch Target Identification (BTI) + support to the ARMv8-M ports. We thank @AhmedIsmail02 for their + contribution. + + Add Floating Point Unit (FPU) support to the ARM_AARCH64 port. We thank + @StefanBalt for their contribution. + + Add FPU Safe Application IRQ Handler suport to the ARM_AARCH64_SRE port. + We thank @GhMarwen for their contribution. + + Add Privileged eXecute Never MPU attribute support to the ARMv8-M ports. + We thank @AhmedIsmail02 for their contribution. + + Update XMOS xcore.ai port to be compatible with FreeRTOS Kernel version + 11. We thank @ACascarino for their contribution. + + ARM_CRx_No_GIC port updates: + - Remove inline assembly and move assembly code to separate portASM.S + file. + - Add support for Floating Point Unit (FPU). + - Add support to allow the application writer to handle SVC calls raised + from the application code. + - Add support for vApplicationFPUSafeIRQHandler. + + POSIX port updates: + - Set PTHREAD_MUTEX_ROBUST attribute on the mutex to prevent application + hangs when a thread dies while holding a mutex. + - Avoid calling pthread_sigmask on non-FreeROS threads when + vPortEndScheduler is called from a non-FreeRTOS thread. We thank + @johnboiles for their contribution. + - Remove unnecessary call to pthread_attr_setstacksize. We thank + @hollinsky for their contribution. + - Add an assert to catch if vPortYield is called from a non-FreeRTOS + thread. We thank @johnboiles for their contribution. + - Fix Posix port compilation on FreeBSD. We thank @tymmej for their + contribution. + + Update the Xtensa port and move it to the Partner-Supported-Ports + repository. We thank @ianstcdns for their contribution. + + Add vPortGenerateSimulatedInterruptFromWindowsThread API in the MSVC-MingW + port to enable native windows thread to synchronize with FreeRTOS task + through simulated interrupt. + + Update Windows port to use Waitable Timer instead of Sleep to improve tick + accuracy. We thank @bknicholls and @leegeth for their contribution. + + Update the value of queueQUEUE_TYPE_SET to a unique value (5) to allow + tracers to differentiate between queues and queue sets. We thank @schilkp + for their contribution. + + Add traceSTARTING_SCHEDULER tracing hook to enable tracers to run code on + startup. We thank @schilkp for their contribution. + + Define vApplicationGetTimerTaskMemory only when configUSE_TIMERS is set to + 1. We thank @HazardyKnusperkeks for their contribution. + + Reset xNextTaskUnblockTime in task notify FromISR APIs to allow the core + to enter sleep mode at the earliest possible time when using tickless + idle. + + Optimize xTaskIncrementTick for SMP by removing xYieldRequiredForCore. We + thank @cymizer for their contribution. + + Update the SMP scheduler to re-select a core to yield when the core + affinity of a ready task is changed. + + Update xEventGroupSetBits to read the event bits value to be returned to + the caller while the scheduler is suspended. This fixes dereference after + the event group is deleted by higher priority task. We thank @skotopes for + their contribution. + + Optimize certain getter APIs by removing unnecessary calls to + task{ENTER|EXIT}_CRITICAL() when the data access is atomic. We thank + @GuilhermeGiacomoSimoes for their contribution. + + Optimize xTaskNotifyWait and ulTaskNotifyTake APIs to suspend the + scheduler only if the task is not already notified, and the caller is + willing to wait for the notification. We thank @jefftenney for + their contribution. + + Fix error checking of prvCreateIdleTasks. We thank @kakkoko for their + contribution. + + Update SMP lock macros and critical nesting macros to pass core ID as an + argument. This reduces the number of accesses to a peripheral register to + query core ID. We thank @felixvanoost for their contribution. + + Add stack pointer bounds check when configCHECK_FOR_STACK_OVERFLOW is set + to 2 to improve reliability of stack overflow detection. We thank + @jiladahe1997 for their contribution. + + Update run-time stats to include time elapsed since the last context + switch for the currently running task. + + Add xQueueCreateSetStatic API for static creation of Queue Sets. We thank + @kzorer for their contribution. + + Update the traceMALLOC() macro to pass the actual size of the allocated + block for secure_heap, heap_2, heap_4 and heap_5. We thank @DazzlingOkami + for their contribution. + + Update heap_1 to use heapADD_WILL_OVERFLOW macro to improve readability. + We thank @wdfk-prog for their contribution. + + Add pointer protection to the pxNextFreeBlock member of the allocated + block's metadata in heap_4 and heap_5 when configENABLE_HEAP_PROTECTOR is + set to 1. We thank @Saiiijchan for their contribution. + + Allow the application writer to override pointer validation for heap_5 + when configENABLE_HEAP_PROTECTOR is used. We thank @Saiiijchan for their + contribution. + + Add xPortResetHeapMinimumEverFreeHeapSize to heap_4.c and heap_5.c. + We thank @TomasGalbickaNXP for their contribution. + + Add NULL check in the event_create function in the POSIX port. We thank + @laroche for their contribution. + + Use _GNU_SOURCE macro instead of __USE_GNU in the Posix port. We thank + @maxiaogood for their contribution. + + Use the new __ARM_FP macro instead of the deprectred __VFP_FP__ macro in + GCC/ARM_CM7, GCC/ARM_CM4_MPU, and GCC/ARM_CM4F ports. We thank @haydenridd + for their contribution. + + Add portMEMORY_BARRIER definition to the Xtensa port. We thank @superroc + for their contribution. + + Move the hardware include msp430.h to port.c from portmacro.h. We thank + @mayl for their contribution. + + Update ARM assembly syntax for Cortex-M ports. We thank @laroche for their + contribution. + + Update the Windows port to records a pending yield in + vPortCloseRunningThread to ensure that the next tick interrupt schedules + the next task regardless of the value of configUSE_PREEMPTION. + + Fix the context switch issue in the RL78 port. We thank @KeitaKashima for + their contribution. + + Fix compilation issue in ARM CM0 port when using Keil MDK. We thank + @TomasGalbickaNXP for their contribution. + + Fix IA32 port compilation when configUSE_COMMON_INTERRUPT_ENTRY_POINT is + set to 0. We thank @Ryzee119 for their contribution. + + Store configMTIMECMP_BASE_ADDRESS in a 64-bit integer for the RISC-V port. + We thank @vishwamartur for their contribution. + + Fix nested interrupt handling and optimize FPU related context switching + for the F1Kx port. We thank @TrongNguyenR for their contribution. + + Update the RP2040 port to add support for Raspberry Pi Pico SDK 2.0.0. + We thank @kilograham for their contribution. + + Fix the return value of portYIELD_FROM_ISR macro for the MSVC-MingW port. + We thank @wwhheerree for their contribution. + + Optimize vApplicationFPUSafeIRQHandler for the Coretex-A9 port by + removing the unnecessarily preserved callee saved registers. We thank + @Saiiijchan for their contribution. + + Fix the context array size for MPU ports to ensure the saved context + location falls within the reserved context area rather than overlapping + with the next MPU_SETTINGS structure member. + + Update CMake files for RP2040 port to fetch the port from the + Community-Supported-Ports repo. We thank @kilograham for their + contribution. + + Fix CMake file for the GCC ARM_CM0 port to include MPU files. We thank + @0mhu for their contribution. + + Add an example of human readable table generated by vTaskListTasks() in + the function documentation. We thank @wwhheerree for their contribution. + +Changes between FreeRTOS V11.0.1 and FreeRTOS V11.1.0 released April 22, 2024 + + + Add ARMv7-R port with Memory Protection Unit (MPU) support. + + Add Memory Protection Unit (MPU) support to the Cortex-M0 port. + + Add stream batching buffer. A stream batching buffer differs from a stream + buffer when a task reads from a non-empty buffer: + - The task reading from a non-empty stream buffer returns immediately + regardless of the amount of data in the buffer. + - The task reading from a non-empty steam batching buffer blocks until the + amount of data in the buffer exceeds the trigger level or the block time + expires. + We thank @cperkulator for their contribution. + + Add the ability to change task notification index for stream buffers. We + thank @glemco for their contribution. + + Add xStreamBufferResetFromISR and xMessageBufferResetFromISR APIs to reset + stream buffer and message buffer from an Interrupt Service Routine (ISR). + We thank @HagaiMoshe for their contribution. + + Update all the FreeRTOS APIs to use configSTACK_DEPTH_TYPE for stack type. + We thank @feilipu for their contribution. + + Update vTaskEndScheduler to delete the timer and idle tasks, + once the scheduler is stopped. + + Make xTaskGetCurrentTaskHandleForCore() available to the single core + scheduler. We thank @Dazza0 for their contribution. + + Update uxTaskGetSystemState to not use the pxIndex member of the List_t + structure while iterating ready tasks list. The reason is that pxIndex + member must only used to select next ready task to run. We thank + @gemarcano for their inputs. + + Add a config option to the FreeRTOS SMP Kernel to set the default core + affinity mask for tasks created without an affinity mask. We thank @go2sh + for their contribution. + + Add configUSE_EVENT_GROUPS and configUSE_STREAM_BUFFERS configuration + constants to control the inclusion of event group and stream buffer + functionalities. + + Code changes to comply with MISRA C 2012. + + Add 64-bit support to the FreeRTOS Windows Simulator port. We thank @watsk + and @josesimoes for their contributions. + + Add support for 64-bit Microblaze processor to the MicroblazeV9 port. We + thank @mubinsyed for their contribution. + + Add support for MSP430 Embedded Application Binary Interface (EABI) to + the MSP430F449 port to make it work with both MSP430 GCC and MSPGCC + compilers. We thank @Forty-Bot for their contribution. + + Update xPortIsAuthorizedToAccessBuffer() on FreeRTOS ports with MPU + support to grant an unprivileged task access to all the memory before the + scheduler is started. + + Update the POSIX port to pass the FreeRTOS task name to pthread for + readable output in debuggers. We thank @Mixaill for their contribution. + + Update the POSIX port to ignore the user specified stack memory and only + pass the stack size to the pthread API to avoid errors caused when stack size + is smaller than the minimum. We thank @cmorgnaBE for their + contribution. + + Update the POSIX port to use a timer thread for tick interrupts instead of + POSIX timers to address issues with signal handling in non-FreeRTOS + pthreads. We thank @cmorgnaBE for their contribution. + + Update ARM_TFM port to support TF-Mv2.0.0 release of trusted-firmware-m. + We thanks @urutva for their contribution. + + Remove redundant constant pools in ARMv8 ports. We thank @urutva for their + contribution. + + Add APIs to reset the internal state of kernel modules. These APIs are + primarily intended to be used in the testing frameworks that restart the + scheduler. + + Use kernel provided implementations of vApplicationGetIdleTaskMemory() and + vApplicationGetTimerTaskMemory() in the RP2040 port. We thank @dpslwk for + their contribution. + + Fix atomic enter/exit critical section macro definitions in atomic.h for + ports that support nested interrupts. We thank @sebunger for their + contribution. + + Fix compiler warnings in the MSP430F449 port when compiled with the + MSP430 GCC compiler. We thank @Forty-Bot for their contribution. + + Update the scheduler suspension usage in ulTaskGenericNotifyTake and + xTaskGenericNotifyWait() to enhance code readability. We thank @Dazza0 for + their contribution. + + Add support for latest version of MPU wrappers( mpu_wrappers_v2) in CMake. + We thank @IsaacDynamo for their contribution. + + Update CMake support to create only one static library containing both the + kernel common code and the kernel port code. We thank @barnatahmed for + their contribution. + Changes between FreeRTOS V11.0.0 and FreeRTOS V11.0.1 released December 21, 2023 + Updated the SBOM file. @@ -451,7 +663,7 @@ Changes between FreeRTOS V10.4.3 and FreeRTOS V10.4.4 released May 28 2021 in more files. + Other minor updates include adding additional configASSERT() checks and correcting and improving code comments. - + Go look at the smp branch to see the progress towards the Symetric + + Go look at the smp branch to see the progress towards the Symmetric Multiprocessing Kernel. https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp Changes between FreeRTOS V10.4.2 and FreeRTOS V10.4.3 released December 14 2020 @@ -1938,7 +2150,7 @@ Changes between V6.1.0 and V6.1.1 released January 14 2011 Embedded Workbench. + Added a new port for the MSP430X core using the IAR Embedded Workbench. + Updated all the RX62N demo projects that target the Renesas Demonstration - Kit (RDK) to take into account the revered LED wiring on later hardware + Kit (RDK) to take into account the reversed LED wiring on later hardware revisions, and the new J-Link debug interface DLL. + Updated all the RX62N demo projects so the IO page served by the example embedded web server works with all web browsers. @@ -3097,7 +3309,7 @@ Changes between V1.2.3 and V1.2.4 xSerialPortInitMinimal() and the function xPortInit() has been renamed to xSerialPortInit(). + The function sSerialPutChar() has been renamed cSerialPutChar() and - the function return type chaned to portCHAR. + the function return type changed to portCHAR. + The integer and flop tasks now include calls to tskYIELD(), allowing them to be used with the cooperative scheduler. + All the demo applications now use the integer and comtest tasks when the @@ -3231,7 +3443,7 @@ Changes between V1.01 and V1.2.0 ports to allocate a different maximum number of priorities. + By default the trace facility is off, previously USE_TRACE_FACILITY was defined. - + comtest.c now uses a psuedo random delay between sends. This allows for + + comtest.c now uses a pseudo random delay between sends. This allows for better testing as the interrupts do not arrive at regular intervals. + Minor change to the Flashlite serial port driver. The driver is written to demonstrate the scheduler and is not written to be efficient. diff --git a/MISRA.md b/MISRA.md index 8d501e0bd..87ff4cbcd 100644 --- a/MISRA.md +++ b/MISRA.md @@ -2,11 +2,11 @@ FreeRTOS-Kernel conforms to [MISRA C:2012](https://www.misra.org.uk/misra-c) guidelines, with the deviations listed below. Compliance is checked with -Coverity static analysis. Since the FreeRTOS kernel is designed for -small-embedded devices, it needs to have a very small memory footprint and -has to be efficient. To achieve that and to increase the performance, it -deviates from some MISRA rules. The specific deviations, suppressed inline, -are listed below. +Coverity static analysis version 2023.6.1. Since the FreeRTOS kernel is +designed for small-embedded devices, it needs to have a very small memory +footprint and has to be efficient. To achieve that and to increase the +performance, it deviates from some MISRA rules. The specific deviations, +suppressed inline, are listed below. Additionally, [MISRA configuration file](examples/coverity/coverity_misra.config) contains project wide deviations. @@ -18,6 +18,14 @@ with ( Assuming rule 8.4 violation; with justification in point 1 ): grep 'MISRA Ref 8.4.1' . -rI ``` +#### Dir 4.7 +MISRA C:2012 Dir 4.7: If a function returns error information, then that error +information shall be tested. + +_Ref 4.7.1_ + - `taskENTER_CRITICAL_FROM_ISR` returns the interrupt mask and not any error + information. Therefore, there is no need test the return value. + #### Rule 8.4 MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an @@ -107,6 +115,25 @@ _Ref 11.5.5_ because data storage buffers are implemented as uint8_t arrays for the ease of sizing, alignment and access. +#### Rule 14.3 + +MISRA C-2012 Rule 14.3: Controlling expressions shall not be invariant. + +_Ref 14.3_ + - The `configMAX_TASK_NAME_LEN` , `taskRESERVED_TASK_NAME_LENGTH` and `SIZE_MAX` + are evaluated to constants at compile time and may vary based on the build + configuration. + +#### Rule 18.1 + +MISRA C-2012 Rule 18.1: A pointer resulting from arithmetic on a pointer operand +shall address an element of the same array as that pointer operand. + +_Ref 18.1_ + - Array access remains within bounds since either the null terminator in + the IDLE task name will break the loop, or the loop will break normally + if the array size is smaller than the IDLE task name length. + #### Rule 21.6 MISRA C-2012 Rule 21.6: The Standard Library input/output functions shall not diff --git a/README.md b/README.md index 7a60f3594..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 @@ -14,16 +14,22 @@ application projects. That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the -[FreeRTOS Kernel Quick Start Guide](https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html) +[FreeRTOS Kernel Quick Start Guide](https://www.freertos.org/Documentation/01-FreeRTOS-quick-start/01-Beginners-guide/02-Quick-start-guide) for detailed instructions and other useful links. Additionally, for FreeRTOS kernel feature information refer to the -[Developer Documentation](https://www.FreeRTOS.org/features.html), -and [API Reference](https://www.FreeRTOS.org/a00106.html). +[Developer Documentation](https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/00-Developer-docs), +and [API Reference](https://www.freertos.org/Documentation/02-Kernel/04-API-references/01-Task-creation/00-TaskHandle). Also for contributing and creating a Pull Request please refer to [the instructions here](.github/CONTRIBUTING.md#contributing-via-pull-request). +**FreeRTOS-Kernel V11.1.0 +[source code](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/V11.1.0) is part +of the +[FreeRTOS 202406.00 LTS](https://github.com/FreeRTOS/FreeRTOS-LTS/tree/202406-LTS) +release.** + ### Getting help If you have any questions or need assistance troubleshooting your FreeRTOS project, @@ -180,3 +186,7 @@ then sort the list, which can be done by running the bash command: Note that only the FreeRTOS-Kernel Source Files, [include](include), [portable/MemMang](portable/MemMang), and [portable/Common](portable/Common) files are checked for proper spelling, and formatting at this time. + +## Third Party Tools +Visit [this link](.github/third_party_tools.md) for detailed information about +third-party tools with FreeRTOS support. diff --git a/croutine.c b/croutine.c index daa88275f..84e1b99bd 100644 --- a/croutine.c +++ b/croutine.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -30,7 +30,7 @@ #include "task.h" #include "croutine.h" -/* Remove the whole file is co-routines are not being used. */ +/* Remove the whole file if co-routines are not being used. */ #if ( configUSE_CO_ROUTINES != 0 ) /* @@ -52,8 +52,10 @@ /* Other file private variables. --------------------------------*/ CRCB_t * pxCurrentCoRoutine = NULL; - static UBaseType_t uxTopCoRoutineReadyPriority = 0; - static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + static UBaseType_t uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U; + static TickType_t xCoRoutineTickCount = ( TickType_t ) 0U; + static TickType_t xLastTickCount = ( TickType_t ) 0U; + static TickType_t xPassedTicks = ( TickType_t ) 0U; /* The initial state of the co-routine when it is created. */ #define corINITIAL_STATE ( 0 ) @@ -378,5 +380,26 @@ return xReturn; } +/*-----------------------------------------------------------*/ + +/* + * Reset state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ + void vCoRoutineResetState( void ) + { + /* Lists for ready and blocked co-routines. */ + pxDelayedCoRoutineList = NULL; + pxOverflowDelayedCoRoutineList = NULL; + + /* Other file private variables. */ + pxCurrentCoRoutine = NULL; + uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U; + xCoRoutineTickCount = ( TickType_t ) 0U; + xLastTickCount = ( TickType_t ) 0U; + xPassedTicks = ( TickType_t ) 0U; + } +/*-----------------------------------------------------------*/ #endif /* configUSE_CO_ROUTINES == 0 */ diff --git a/event_groups.c b/event_groups.c index 3fac0d9c8..1923bf78d 100644 --- a/event_groups.c +++ b/event_groups.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -30,7 +30,7 @@ #include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining - * all the API functions to use the MPU wrappers. That should only be done when + * all the API functions to use the MPU wrappers. That should only be done when * task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE @@ -45,19 +45,25 @@ * correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE -typedef struct EventGroupDef_t -{ - EventBits_t uxEventBits; - List_t xTasksWaitingForBits; /**< List of tasks waiting for a bit to be set. */ +/* This entire source file will be skipped if the application is not configured + * to include event groups functionality. This #if is closed at the very bottom + * of this file. If you want to include event groups then ensure + * configUSE_EVENT_GROUPS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_EVENT_GROUPS == 1 ) - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxEventGroupNumber; - #endif + typedef struct EventGroupDef_t + { + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /**< List of tasks waiting for a bit to be set. */ - #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ - #endif -} EventGroup_t; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + #endif + } EventGroup_t; /*-----------------------------------------------------------*/ @@ -69,363 +75,207 @@ typedef struct EventGroupDef_t * wait condition is met if any of the bits set in uxBitsToWait for are also set * in uxCurrentEventBits. */ -static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, - const EventBits_t uxBitsToWaitFor, - const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; + static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) - { - EventGroup_t * pxEventBits; - - traceENTER_xEventGroupCreateStatic( pxEventGroupBuffer ); - - /* A StaticEventGroup_t object must be provided. */ - configASSERT( pxEventGroupBuffer ); - - #if ( configASSERT_DEFINED == 1 ) + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) { - /* Sanity check that the size of the structure used to declare a - * variable of type StaticEventGroup_t equals the size of the real - * event group structure. */ - volatile size_t xSize = sizeof( StaticEventGroup_t ); - configASSERT( xSize == sizeof( EventGroup_t ) ); - } - #endif /* configASSERT_DEFINED */ + EventGroup_t * pxEventBits; - /* The user has provided a statically allocated event group - use it. */ - /* MISRA Ref 11.3.1 [Misaligned access] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ - /* coverity[misra_c_2012_rule_11_3_violation] */ - pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; + traceENTER_xEventGroupCreateStatic( pxEventGroupBuffer ); - if( pxEventBits != NULL ) - { - pxEventBits->uxEventBits = 0; - vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + /* A StaticEventGroup_t object must be provided. */ + configASSERT( pxEventGroupBuffer ); - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #if ( configASSERT_DEFINED == 1 ) { - /* Both static and dynamic allocation can be used, so note that - * this event group was created statically in case the event group - * is later deleted. */ - pxEventBits->ucStaticallyAllocated = pdTRUE; + /* Sanity check that the size of the structure used to declare a + * variable of type StaticEventGroup_t equals the size of the real + * event group structure. */ + volatile size_t xSize = sizeof( StaticEventGroup_t ); + configASSERT( xSize == sizeof( EventGroup_t ) ); } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + #endif /* configASSERT_DEFINED */ - traceEVENT_GROUP_CREATE( pxEventBits ); - } - else - { - /* xEventGroupCreateStatic should only ever be called with - * pxEventGroupBuffer pointing to a pre-allocated (compile time - * allocated) StaticEventGroup_t variable. */ - traceEVENT_GROUP_CREATE_FAILED(); - } + /* The user has provided a statically allocated event group - use it. */ + /* MISRA Ref 11.3.1 [Misaligned access] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ + /* coverity[misra_c_2012_rule_11_3_violation] */ + pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; - traceRETURN_xEventGroupCreateStatic( pxEventBits ); - - return pxEventBits; - } - -#endif /* configSUPPORT_STATIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - - EventGroupHandle_t xEventGroupCreate( void ) - { - EventGroup_t * pxEventBits; - - traceENTER_xEventGroupCreate(); - - /* MISRA Ref 11.5.1 [Malloc memory assignment] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); - - if( pxEventBits != NULL ) - { - pxEventBits->uxEventBits = 0; - vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); - - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + if( pxEventBits != NULL ) { - /* Both static and dynamic allocation can be used, so note this - * event group was allocated statically in case the event group is - * later deleted. */ - pxEventBits->ucStaticallyAllocated = pdFALSE; - } - #endif /* configSUPPORT_STATIC_ALLOCATION */ + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); - traceEVENT_GROUP_CREATE( pxEventBits ); - } - else - { - traceEVENT_GROUP_CREATE_FAILED(); - } + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note that + * this event group was created statically in case the event group + * is later deleted. */ + pxEventBits->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - traceRETURN_xEventGroupCreate( pxEventBits ); - - return pxEventBits; - } - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - -EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) -{ - EventBits_t uxOriginalBitValue, uxReturn; - EventGroup_t * pxEventBits = xEventGroup; - BaseType_t xAlreadyYielded; - BaseType_t xTimeoutOccurred = pdFALSE; - - traceENTER_xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); - - configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); - configASSERT( uxBitsToWaitFor != 0 ); - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - { - configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); - } - #endif - - vTaskSuspendAll(); - { - uxOriginalBitValue = pxEventBits->uxEventBits; - - ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); - - if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) - { - /* All the rendezvous bits are now set - no need to block. */ - uxReturn = ( uxOriginalBitValue | uxBitsToSet ); - - /* Rendezvous always clear the bits. They will have been cleared - * already unless this is the only task in the rendezvous. */ - pxEventBits->uxEventBits &= ~uxBitsToWaitFor; - - xTicksToWait = 0; - } - else - { - if( xTicksToWait != ( TickType_t ) 0 ) - { - traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); - - /* Store the bits that the calling task is waiting for in the - * task's event list item so the kernel knows when a match is - * found. Then enter the blocked state. */ - vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); - - /* This assignment is obsolete as uxReturn will get set after - * the task unblocks, but some compilers mistakenly generate a - * warning about uxReturn being returned without being set if the - * assignment is omitted. */ - uxReturn = 0; + traceEVENT_GROUP_CREATE( pxEventBits ); } else { - /* The rendezvous bits were not set, but no block time was - * specified - just return the current event bit value. */ - uxReturn = pxEventBits->uxEventBits; - xTimeoutOccurred = pdTRUE; + /* xEventGroupCreateStatic should only ever be called with + * pxEventGroupBuffer pointing to a pre-allocated (compile time + * allocated) StaticEventGroup_t variable. */ + traceEVENT_GROUP_CREATE_FAILED(); } - } - } - xAlreadyYielded = xTaskResumeAll(); - if( xTicksToWait != ( TickType_t ) 0 ) - { - if( xAlreadyYielded == pdFALSE ) - { - taskYIELD_WITHIN_API(); - } - else - { - mtCOVERAGE_TEST_MARKER(); + traceRETURN_xEventGroupCreateStatic( pxEventBits ); + + return pxEventBits; } - /* The task blocked to wait for its required bits to be set - at this - * point either the required bits were set or the block time expired. If - * the required bits were set they will have been stored in the task's - * event list item, and they should now be retrieved then cleared. */ - uxReturn = uxTaskResetEventItemValue(); + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ - if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreate( void ) { - /* The task timed out, just return the current event bit value. */ - taskENTER_CRITICAL(); + EventGroup_t * pxEventBits; + + traceENTER_xEventGroupCreate(); + + /* MISRA Ref 11.5.1 [Malloc memory assignment] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ + /* coverity[misra_c_2012_rule_11_5_violation] */ + pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); + + if( pxEventBits != NULL ) { - uxReturn = pxEventBits->uxEventBits; + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); - /* Although the task got here because it timed out before the - * bits it was waiting for were set, it is possible that since it - * unblocked another task has set the bits. If this is the case - * then it needs to clear the bits before exiting. */ - if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { - pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + /* Both static and dynamic allocation can be used, so note this + * event group was allocated statically in case the event group is + * later deleted. */ + pxEventBits->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); + } + + traceRETURN_xEventGroupCreate( pxEventBits ); + + return pxEventBits; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) + { + EventBits_t uxOriginalBitValue, uxReturn; + EventGroup_t * pxEventBits = xEventGroup; + BaseType_t xAlreadyYielded; + BaseType_t xTimeoutOccurred = pdFALSE; + + traceENTER_xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + uxOriginalBitValue = pxEventBits->uxEventBits; + + ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + /* All the rendezvous bits are now set - no need to block. */ + uxReturn = ( uxOriginalBitValue | uxBitsToSet ); + + /* Rendezvous always clear the bits. They will have been cleared + * already unless this is the only task in the rendezvous. */ + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + + xTicksToWait = 0; + } + else + { + if( xTicksToWait != ( TickType_t ) 0 ) + { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + + /* Store the bits that the calling task is waiting for in the + * task's event list item so the kernel knows when a match is + * found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); + + /* This assignment is obsolete as uxReturn will get set after + * the task unblocks, but some compilers mistakenly generate a + * warning about uxReturn being returned without being set if the + * assignment is omitted. */ + uxReturn = 0; } else { - mtCOVERAGE_TEST_MARKER(); + /* The rendezvous bits were not set, but no block time was + * specified - just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + xTimeoutOccurred = pdTRUE; } } - taskEXIT_CRITICAL(); - - xTimeoutOccurred = pdTRUE; } - else + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) { - /* The task unblocked because the bits were set. */ - } - - /* Control bits might be set as the task had blocked should not be - * returned. */ - uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; - } - - traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); - - /* Prevent compiler warnings when trace macros are not used. */ - ( void ) xTimeoutOccurred; - - traceRETURN_xEventGroupSync( uxReturn ); - - return uxReturn; -} -/*-----------------------------------------------------------*/ - -EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToWaitFor, - const BaseType_t xClearOnExit, - const BaseType_t xWaitForAllBits, - TickType_t xTicksToWait ) -{ - EventGroup_t * pxEventBits = xEventGroup; - EventBits_t uxReturn, uxControlBits = 0; - BaseType_t xWaitConditionMet, xAlreadyYielded; - BaseType_t xTimeoutOccurred = pdFALSE; - - traceENTER_xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); - - /* Check the user is not attempting to wait on the bits used by the kernel - * itself, and that at least one bit is being requested. */ - configASSERT( xEventGroup ); - configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); - configASSERT( uxBitsToWaitFor != 0 ); - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - { - configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); - } - #endif - - vTaskSuspendAll(); - { - const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; - - /* Check to see if the wait condition is already met or not. */ - xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); - - if( xWaitConditionMet != pdFALSE ) - { - /* The wait condition has already been met so there is no need to - * block. */ - uxReturn = uxCurrentEventBits; - xTicksToWait = ( TickType_t ) 0; - - /* Clear the wait bits if requested to do so. */ - if( xClearOnExit != pdFALSE ) + if( xAlreadyYielded == pdFALSE ) { - pxEventBits->uxEventBits &= ~uxBitsToWaitFor; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else if( xTicksToWait == ( TickType_t ) 0 ) - { - /* The wait condition has not been met, but no block time was - * specified, so just return the current value. */ - uxReturn = uxCurrentEventBits; - xTimeoutOccurred = pdTRUE; - } - else - { - /* The task is going to block to wait for its required bits to be - * set. uxControlBits are used to remember the specified behaviour of - * this call to xEventGroupWaitBits() - for use when the event bits - * unblock the task. */ - if( xClearOnExit != pdFALSE ) - { - uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + taskYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } - if( xWaitForAllBits != pdFALSE ) - { - uxControlBits |= eventWAIT_FOR_ALL_BITS; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* The task blocked to wait for its required bits to be set - at this + * point either the required bits were set or the block time expired. If + * the required bits were set they will have been stored in the task's + * event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); - /* Store the bits that the calling task is waiting for in the - * task's event list item so the kernel knows when a match is - * found. Then enter the blocked state. */ - vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); - - /* This is obsolete as it will get set after the task unblocks, but - * some compilers mistakenly generate a warning about the variable - * being returned without being set if it is not done. */ - uxReturn = 0; - - traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); - } - } - xAlreadyYielded = xTaskResumeAll(); - - if( xTicksToWait != ( TickType_t ) 0 ) - { - if( xAlreadyYielded == pdFALSE ) - { - taskYIELD_WITHIN_API(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - /* The task blocked to wait for its required bits to be set - at this - * point either the required bits were set or the block time expired. If - * the required bits were set they will have been stored in the task's - * event list item, and they should now be retrieved then cleared. */ - uxReturn = uxTaskResetEventItemValue(); - - if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) - { - taskENTER_CRITICAL(); + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) { /* The task timed out, just return the current event bit value. */ - uxReturn = pxEventBits->uxEventBits; - - /* It is possible that the event bits were updated between this - * task leaving the Blocked state and running again. */ - if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + taskENTER_CRITICAL(); { - if( xClearOnExit != pdFALSE ) + uxReturn = pxEventBits->uxEventBits; + + /* Although the task got here because it timed out before the + * bits it was waiting for were set, it is possible that since it + * unblocked another task has set the bits. If this is the case + * then it needs to clear the bits before exiting. */ + if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) { pxEventBits->uxEventBits &= ~uxBitsToWaitFor; } @@ -434,437 +284,604 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, mtCOVERAGE_TEST_MARKER(); } } + taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* Control bits might be set as the task had blocked should not be + * returned. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + traceRETURN_xEventGroupSync( uxReturn ); + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) + { + EventGroup_t * pxEventBits = xEventGroup; + EventBits_t uxReturn, uxControlBits = 0; + BaseType_t xWaitConditionMet, xAlreadyYielded; + BaseType_t xTimeoutOccurred = pdFALSE; + + traceENTER_xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + + /* Check the user is not attempting to wait on the bits used by the kernel + * itself, and that at least one bit is being requested. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; + + /* Check to see if the wait condition is already met or not. */ + xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); + + if( xWaitConditionMet != pdFALSE ) + { + /* The wait condition has already been met so there is no need to + * block. */ + uxReturn = uxCurrentEventBits; + xTicksToWait = ( TickType_t ) 0; + + /* Clear the wait bits if requested to do so. */ + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The wait condition has not been met, but no block time was + * specified, so just return the current value. */ + uxReturn = uxCurrentEventBits; + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task is going to block to wait for its required bits to be + * set. uxControlBits are used to remember the specified behaviour of + * this call to xEventGroupWaitBits() - for use when the event bits + * unblock the task. */ + if( xClearOnExit != pdFALSE ) + { + uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + } else { mtCOVERAGE_TEST_MARKER(); } - xTimeoutOccurred = pdTRUE; - } - taskEXIT_CRITICAL(); - } - else - { - /* The task unblocked because the bits were set. */ - } - - /* The task blocked so control bits may have been set. */ - uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; - } - - traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); - - /* Prevent compiler warnings when trace macros are not used. */ - ( void ) xTimeoutOccurred; - - traceRETURN_xEventGroupWaitBits( uxReturn ); - - return uxReturn; -} -/*-----------------------------------------------------------*/ - -EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) -{ - EventGroup_t * pxEventBits = xEventGroup; - EventBits_t uxReturn; - - traceENTER_xEventGroupClearBits( xEventGroup, uxBitsToClear ); - - /* Check the user is not attempting to clear the bits used by the kernel - * itself. */ - configASSERT( xEventGroup ); - configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); - - taskENTER_CRITICAL(); - { - traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); - - /* The value returned is the event group value prior to the bits being - * cleared. */ - uxReturn = pxEventBits->uxEventBits; - - /* Clear the bits. */ - pxEventBits->uxEventBits &= ~uxBitsToClear; - } - taskEXIT_CRITICAL(); - - traceRETURN_xEventGroupClearBits( uxReturn ); - - return uxReturn; -} -/*-----------------------------------------------------------*/ - -#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) - - BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) - { - BaseType_t xReturn; - - traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ); - - traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); - xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); - - traceRETURN_xEventGroupClearBitsFromISR( xReturn ); - - return xReturn; - } - -#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ -/*-----------------------------------------------------------*/ - -EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) -{ - UBaseType_t uxSavedInterruptStatus; - EventGroup_t const * const pxEventBits = xEventGroup; - EventBits_t uxReturn; - - traceENTER_xEventGroupGetBitsFromISR( xEventGroup ); - - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); - { - uxReturn = pxEventBits->uxEventBits; - } - taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); - - traceRETURN_xEventGroupGetBitsFromISR( uxReturn ); - - return uxReturn; -} -/*-----------------------------------------------------------*/ - -EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) -{ - ListItem_t * pxListItem; - ListItem_t * pxNext; - ListItem_t const * pxListEnd; - List_t const * pxList; - EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; - EventGroup_t * pxEventBits = xEventGroup; - BaseType_t xMatchFound = pdFALSE; - - traceENTER_xEventGroupSetBits( xEventGroup, uxBitsToSet ); - - /* Check the user is not attempting to set the bits used by the kernel - * itself. */ - configASSERT( xEventGroup ); - configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); - - pxList = &( pxEventBits->xTasksWaitingForBits ); - pxListEnd = listGET_END_MARKER( pxList ); - vTaskSuspendAll(); - { - traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); - - pxListItem = listGET_HEAD_ENTRY( pxList ); - - /* Set the bits. */ - pxEventBits->uxEventBits |= uxBitsToSet; - - /* See if the new bit value should unblock any tasks. */ - while( pxListItem != pxListEnd ) - { - pxNext = listGET_NEXT( pxListItem ); - uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); - xMatchFound = pdFALSE; - - /* Split the bits waited for from the control bits. */ - uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; - uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; - - if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) - { - /* Just looking for single bit being set. */ - if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + if( xWaitForAllBits != pdFALSE ) { + uxControlBits |= eventWAIT_FOR_ALL_BITS; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the bits that the calling task is waiting for in the + * task's event list item so the kernel knows when a match is + * found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); + + /* This is obsolete as it will get set after the task unblocks, but + * some compilers mistakenly generate a warning about the variable + * being returned without being set if it is not done. */ + uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + taskYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + * point either the required bits were set or the block time expired. If + * the required bits were set they will have been stored in the task's + * event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + taskENTER_CRITICAL(); + { + /* The task timed out, just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + + /* It is possible that the event bits were updated between this + * task leaving the Blocked state and running again. */ + if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + { + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xTimeoutOccurred = pdTRUE; + } + taskEXIT_CRITICAL(); + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* The task blocked so control bits may have been set. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + traceRETURN_xEventGroupWaitBits( uxReturn ); + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) + { + EventGroup_t * pxEventBits = xEventGroup; + EventBits_t uxReturn; + + traceENTER_xEventGroupClearBits( xEventGroup, uxBitsToClear ); + + /* Check the user is not attempting to clear the bits used by the kernel + * itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + taskENTER_CRITICAL(); + { + traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); + + /* The value returned is the event group value prior to the bits being + * cleared. */ + uxReturn = pxEventBits->uxEventBits; + + /* Clear the bits. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + taskEXIT_CRITICAL(); + + traceRETURN_xEventGroupClearBits( uxReturn ); + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + #if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) + { + BaseType_t xReturn; + + traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ); + + traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); + + traceRETURN_xEventGroupClearBitsFromISR( xReturn ); + + return xReturn; + } + + #endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + + EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) + { + UBaseType_t uxSavedInterruptStatus; + EventGroup_t const * const pxEventBits = xEventGroup; + EventBits_t uxReturn; + + traceENTER_xEventGroupGetBitsFromISR( xEventGroup ); + + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + { + uxReturn = pxEventBits->uxEventBits; + } + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); + + traceRETURN_xEventGroupGetBitsFromISR( uxReturn ); + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) + { + ListItem_t * pxListItem; + ListItem_t * pxNext; + ListItem_t const * pxListEnd; + List_t const * pxList; + EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits, uxReturnBits; + EventGroup_t * pxEventBits = xEventGroup; + BaseType_t xMatchFound = pdFALSE; + + traceENTER_xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + /* Check the user is not attempting to set the bits used by the kernel + * itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + pxList = &( pxEventBits->xTasksWaitingForBits ); + pxListEnd = listGET_END_MARKER( pxList ); + vTaskSuspendAll(); + { + traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); + + pxListItem = listGET_HEAD_ENTRY( pxList ); + + /* Set the bits. */ + pxEventBits->uxEventBits |= uxBitsToSet; + + /* See if the new bit value should unblock any tasks. */ + while( pxListItem != pxListEnd ) + { + pxNext = listGET_NEXT( pxListItem ); + uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); + xMatchFound = pdFALSE; + + /* Split the bits waited for from the control bits. */ + uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; + uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; + + if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) + { + /* Just looking for single bit being set. */ + if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + { + xMatchFound = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + { + /* All bits are set. */ xMatchFound = pdTRUE; } else { - mtCOVERAGE_TEST_MARKER(); + /* Need all bits to be set, but not all the bits were set. */ } + + if( xMatchFound != pdFALSE ) + { + /* The bits match. Should the bits be cleared on exit? */ + if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + { + uxBitsToClear |= uxBitsWaitedFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the actual event flag value in the task's event list + * item before removing the task from the event list. The + * eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows + * that is was unblocked due to its required bits matching, rather + * than because it timed out. */ + vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + /* Move onto the next list item. Note pxListItem->pxNext is not + * used here as the list item may have been removed from the event list + * and inserted into the ready/pending reading list. */ + pxListItem = pxNext; } - else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + + /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT + * bit was set in the control word. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + + /* Snapshot resulting bits. */ + uxReturnBits = pxEventBits->uxEventBits; + } + ( void ) xTaskResumeAll(); + + traceRETURN_xEventGroupSetBits( uxReturnBits ); + + return uxReturnBits; + } +/*-----------------------------------------------------------*/ + + void vEventGroupDelete( EventGroupHandle_t xEventGroup ) + { + EventGroup_t * pxEventBits = xEventGroup; + const List_t * pxTasksWaitingForBits; + + traceENTER_vEventGroupDelete( xEventGroup ); + + configASSERT( pxEventBits ); + + pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); + + vTaskSuspendAll(); + { + traceEVENT_GROUP_DELETE( xEventGroup ); + + while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) { - /* All bits are set. */ - xMatchFound = pdTRUE; + /* Unblock the task, returning 0 as the event list is being deleted + * and cannot therefore have any bits set. */ + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + } + } + ( void ) xTaskResumeAll(); + + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The event group can only have been allocated dynamically - free + * it again. */ + vPortFree( pxEventBits ); + } + #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The event group could have been allocated statically or + * dynamically, so check before attempting to free the memory. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxEventBits ); } else { - /* Need all bits to be set, but not all the bits were set. */ + mtCOVERAGE_TEST_MARKER(); } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - if( xMatchFound != pdFALSE ) + traceRETURN_vEventGroupDelete(); + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) + { + BaseType_t xReturn; + EventGroup_t * pxEventBits = xEventGroup; + + traceENTER_xEventGroupGetStaticBuffer( xEventGroup, ppxEventGroupBuffer ); + + configASSERT( pxEventBits ); + configASSERT( ppxEventGroupBuffer ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) { - /* The bits match. Should the bits be cleared on exit? */ - if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + /* Check if the event group was statically allocated. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE ) { - uxBitsToClear |= uxBitsWaitedFor; + /* MISRA Ref 11.3.1 [Misaligned access] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ + /* coverity[misra_c_2012_rule_11_3_violation] */ + *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; + xReturn = pdTRUE; } else { - mtCOVERAGE_TEST_MARKER(); + xReturn = pdFALSE; } - - /* Store the actual event flag value in the task's event list - * item before removing the task from the event list. The - * eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows - * that is was unblocked due to its required bits matching, rather - * than because it timed out. */ - vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); } - - /* Move onto the next list item. Note pxListItem->pxNext is not - * used here as the list item may have been removed from the event list - * and inserted into the ready/pending reading list. */ - pxListItem = pxNext; - } - - /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT - * bit was set in the control word. */ - pxEventBits->uxEventBits &= ~uxBitsToClear; - } - ( void ) xTaskResumeAll(); - - traceRETURN_xEventGroupSetBits( pxEventBits->uxEventBits ); - - return pxEventBits->uxEventBits; -} -/*-----------------------------------------------------------*/ - -void vEventGroupDelete( EventGroupHandle_t xEventGroup ) -{ - EventGroup_t * pxEventBits = xEventGroup; - const List_t * pxTasksWaitingForBits; - - traceENTER_vEventGroupDelete( xEventGroup ); - - configASSERT( pxEventBits ); - - pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); - - vTaskSuspendAll(); - { - traceEVENT_GROUP_DELETE( xEventGroup ); - - while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) - { - /* Unblock the task, returning 0 as the event list is being deleted - * and cannot therefore have any bits set. */ - configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); - vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); - } - } - ( void ) xTaskResumeAll(); - - #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) - { - /* The event group can only have been allocated dynamically - free - * it again. */ - vPortFree( pxEventBits ); - } - #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) - { - /* The event group could have been allocated statically or - * dynamically, so check before attempting to free the memory. */ - if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) - { - vPortFree( pxEventBits ); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - - traceRETURN_vEventGroupDelete(); -} -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, - StaticEventGroup_t ** ppxEventGroupBuffer ) - { - BaseType_t xReturn; - EventGroup_t * pxEventBits = xEventGroup; - - traceENTER_xEventGroupGetStaticBuffer( xEventGroup, ppxEventGroupBuffer ); - - configASSERT( pxEventBits ); - configASSERT( ppxEventGroupBuffer ); - - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - /* Check if the event group was statically allocated. */ - if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE ) + #else /* configSUPPORT_DYNAMIC_ALLOCATION */ { + /* Event group must have been statically allocated. */ /* MISRA Ref 11.3.1 [Misaligned access] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ /* coverity[misra_c_2012_rule_11_3_violation] */ *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; xReturn = pdTRUE; } - else - { - xReturn = pdFALSE; - } - } - #else /* configSUPPORT_DYNAMIC_ALLOCATION */ - { - /* Event group must have been statically allocated. */ - /* MISRA Ref 11.3.1 [Misaligned access] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ - /* coverity[misra_c_2012_rule_11_3_violation] */ - *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; - xReturn = pdTRUE; - } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - traceRETURN_xEventGroupGetStaticBuffer( xReturn ); + traceRETURN_xEventGroupGetStaticBuffer( xReturn ); - return xReturn; - } -#endif /* configSUPPORT_STATIC_ALLOCATION */ + return xReturn; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ /* For internal use only - execute a 'set bits' command that was pended from * an interrupt. */ -void vEventGroupSetBitsCallback( void * pvEventGroup, - uint32_t ulBitsToSet ) -{ - traceENTER_vEventGroupSetBitsCallback( pvEventGroup, ulBitsToSet ); + void vEventGroupSetBitsCallback( void * pvEventGroup, + uint32_t ulBitsToSet ) + { + traceENTER_vEventGroupSetBitsCallback( pvEventGroup, ulBitsToSet ); - /* MISRA Ref 11.5.4 [Callback function parameter] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); + /* MISRA Ref 11.5.4 [Callback function parameter] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ + /* coverity[misra_c_2012_rule_11_5_violation] */ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); - traceRETURN_vEventGroupSetBitsCallback(); -} + traceRETURN_vEventGroupSetBitsCallback(); + } /*-----------------------------------------------------------*/ /* For internal use only - execute a 'clear bits' command that was pended from * an interrupt. */ -void vEventGroupClearBitsCallback( void * pvEventGroup, - uint32_t ulBitsToClear ) -{ - traceENTER_vEventGroupClearBitsCallback( pvEventGroup, ulBitsToClear ); - - /* MISRA Ref 11.5.4 [Callback function parameter] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); - - traceRETURN_vEventGroupClearBitsCallback(); -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, - const EventBits_t uxBitsToWaitFor, - const BaseType_t xWaitForAllBits ) -{ - BaseType_t xWaitConditionMet = pdFALSE; - - if( xWaitForAllBits == pdFALSE ) + void vEventGroupClearBitsCallback( void * pvEventGroup, + uint32_t ulBitsToClear ) { - /* Task only has to wait for one bit within uxBitsToWaitFor to be - * set. Is one already set? */ - if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) - { - xWaitConditionMet = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - /* Task has to wait for all the bits in uxBitsToWaitFor to be set. - * Are they set already? */ - if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) - { - xWaitConditionMet = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } + traceENTER_vEventGroupClearBitsCallback( pvEventGroup, ulBitsToClear ); - return xWaitConditionMet; -} -/*-----------------------------------------------------------*/ - -#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) - - BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - BaseType_t * pxHigherPriorityTaskWoken ) - { - BaseType_t xReturn; - - traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ); - - traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); - xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); - - traceRETURN_xEventGroupSetBitsFromISR( xReturn ); - - return xReturn; - } - -#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) - { - UBaseType_t xReturn; - - /* MISRA Ref 11.5.2 [Opaque pointer] */ + /* MISRA Ref 11.5.4 [Callback function parameter] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ /* coverity[misra_c_2012_rule_11_5_violation] */ - EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); - traceENTER_uxEventGroupGetNumber( xEventGroup ); + traceRETURN_vEventGroupClearBitsCallback(); + } +/*-----------------------------------------------------------*/ - if( xEventGroup == NULL ) + static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xWaitForAllBits ) + { + BaseType_t xWaitConditionMet = pdFALSE; + + if( xWaitForAllBits == pdFALSE ) { - xReturn = 0; + /* Task only has to wait for one bit within uxBitsToWaitFor to be + * set. Is one already set? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } else { - xReturn = pxEventBits->uxEventGroupNumber; + /* Task has to wait for all the bits in uxBitsToWaitFor to be set. + * Are they set already? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } - traceRETURN_uxEventGroupGetNumber( xReturn ); - - return xReturn; + return xWaitConditionMet; } - -#endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ -#if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) - void vEventGroupSetNumber( void * xEventGroup, - UBaseType_t uxEventGroupNumber ) - { - traceENTER_vEventGroupSetNumber( xEventGroup, uxEventGroupNumber ); + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) + { + BaseType_t xReturn; - /* MISRA Ref 11.5.2 [Opaque pointer] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; + traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ); - traceRETURN_vEventGroupSetNumber(); - } + traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); -#endif /* configUSE_TRACE_FACILITY */ + traceRETURN_xEventGroupSetBitsFromISR( xReturn ); + + return xReturn; + } + + #endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) + { + UBaseType_t xReturn; + + /* MISRA Ref 11.5.2 [Opaque pointer] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ + /* coverity[misra_c_2012_rule_11_5_violation] */ + EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; + + traceENTER_uxEventGroupGetNumber( xEventGroup ); + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + traceRETURN_uxEventGroupGetNumber( xReturn ); + + return xReturn; + } + + #endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) + { + traceENTER_vEventGroupSetNumber( xEventGroup, uxEventGroupNumber ); + + /* MISRA Ref 11.5.2 [Opaque pointer] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ + /* coverity[misra_c_2012_rule_11_5_violation] */ + ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; + + traceRETURN_vEventGroupSetNumber(); + } + + #endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured + * to include event groups functionality. If you want to include event groups + * then ensure configUSE_EVENT_GROUPS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_EVENT_GROUPS == 1 */ diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 000000000..3b36b607e --- /dev/null +++ b/examples/README.md @@ -0,0 +1,17 @@ +# README for FreeRTOS-Kernel/examples + +The easiest way to use FreeRTOS is to start with one of the pre-configured demo application projects. +See [FreeRTOS/FreeRTOS/Demo](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS/Demo) to find a list of pre-configured demos on multiple platforms which demonstrate the working of the FreeRTOS-Kernel. +This directory aims to further facilitate the beginners in building their first FreeRTOS project. + + +## Directory Structure: + +* The [cmake_example](./cmake_example) directory contains a minimal FreeRTOS example project, which uses the configuration file in the template_configuration directory listed below. This will provide you with a starting point for building your applications using FreeRTOS-Kernel. +* The [coverity](./coverity) directory contains a project to run [Synopsys Coverity](https://www.synopsys.com/software-integrity/static-analysis-tools-sast/coverity.html) for checking MISRA compliance. This directory contains further readme files and links to documentation. +* The [template_configuration](./template_configuration) directory contains a sample configuration file FreeRTOSConfig.h which helps you in preparing your application configuration + + +## Additional examples + +Additional examples of the kernel being used in real life applications in tandem with many other libraries (i.e. FreeRTOS+TCP, coreMQTT, coreHTTP etc.) can be found [here](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo). diff --git a/examples/cmake_example/CMakeLists.txt b/examples/cmake_example/CMakeLists.txt index bff9317de..7b31cc52a 100644 --- a/examples/cmake_example/CMakeLists.txt +++ b/examples/cmake_example/CMakeLists.txt @@ -1,5 +1,4 @@ cmake_minimum_required(VERSION 3.15) - project(example) set(FREERTOS_KERNEL_PATH "../../") @@ -71,3 +70,5 @@ add_executable(${PROJECT_NAME} ) target_link_libraries(${PROJECT_NAME} freertos_kernel freertos_config) + +set_property(TARGET freertos_kernel PROPERTY C_STANDARD 90) \ No newline at end of file diff --git a/examples/cmake_example/main.c b/examples/cmake_example/main.c index 4825f2d19..96a2abfe1 100644 --- a/examples/cmake_example/main.c +++ b/examples/cmake_example/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -30,7 +30,7 @@ * This is a simple main that will start the FreeRTOS-Kernel and run a periodic task * that only delays if compiled with the template port, this project will do nothing. * For more information on getting started please look here: - * https://freertos.org/FreeRTOS-quick-start-guide.html + * https://www.freertos.org/Documentation/01-FreeRTOS-quick-start/01-Beginners-guide/02-Quick-start-guide */ /* FreeRTOS includes. */ @@ -43,7 +43,13 @@ /* Standard includes. */ #include -void exampleTask( void * parameters ) +/*-----------------------------------------------------------*/ + +static void exampleTask( void * parameters ) __attribute__( ( noreturn ) ); + +/*-----------------------------------------------------------*/ + +static void exampleTask( void * parameters ) { /* Unused parameters. */ ( void ) parameters; @@ -56,20 +62,20 @@ void exampleTask( void * parameters ) } /*-----------------------------------------------------------*/ -void main( void ) +int main( void ) { static StaticTask_t exampleTaskTCB; static StackType_t exampleTaskStack[ configMINIMAL_STACK_SIZE ]; - printf( "Example FreeRTOS Project\n" ); + ( void ) printf( "Example FreeRTOS Project\n" ); - xTaskCreateStatic( exampleTask, - "example", - configMINIMAL_STACK_SIZE, - NULL, - configMAX_PRIORITIES - 1, - &( exampleTaskStack[ 0 ] ), - &( exampleTaskTCB ) ); + ( void ) xTaskCreateStatic( exampleTask, + "example", + configMINIMAL_STACK_SIZE, + NULL, + configMAX_PRIORITIES - 1U, + &( exampleTaskStack[ 0 ] ), + &( exampleTaskTCB ) ); /* Start the scheduler. */ vTaskStartScheduler(); @@ -78,15 +84,21 @@ void main( void ) { /* Should not reach here. */ } + + return 0; } /*-----------------------------------------------------------*/ -void vApplicationStackOverflowHook( TaskHandle_t xTask, - char * pcTaskName ) -{ - /* Check pcTaskName for the name of the offending task, - * or pxCurrentTCB if pcTaskName has itself been corrupted. */ - ( void ) xTask; - ( void ) pcTaskName; -} +#if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) + + void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * pcTaskName ) + { + /* Check pcTaskName for the name of the offending task, + * or pxCurrentTCB if pcTaskName has itself been corrupted. */ + ( void ) xTask; + ( void ) pcTaskName; + } + +#endif /* #if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) */ /*-----------------------------------------------------------*/ diff --git a/examples/coverity/CMakeLists.txt b/examples/coverity/CMakeLists.txt index b4538655e..3c0f4e452 100644 --- a/examples/coverity/CMakeLists.txt +++ b/examples/coverity/CMakeLists.txt @@ -2,8 +2,9 @@ cmake_minimum_required(VERSION 3.15) project(coverity) -set(FREERTOS_KERNEL_PATH "../../") -FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}*.c) +set(FREERTOS_KERNEL_PATH "../..") +FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}/*.c) +FILE(GLOB FREERTOS_PORT_CODE ${FREERTOS_KERNEL_PATH}/portable/template/*.c) # Coverity incorrectly infers the type of pdTRUE and pdFALSE as boolean because # of their names. This generates multiple false positive warnings about type @@ -12,8 +13,8 @@ FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}*.c) # fixes the issue of incorrectly inferring the type of pdTRUE and pdFALSE as # boolean. add_custom_target(fix_source ALL - COMMAND sed -i -b -e 's/pdFALSE/pdFAIL/g' -e 's/pdTRUE/pdPASS/g' ${FREERTOS_KERNEL_SOURCE} - DEPENDS ${FREERTOS_KERNEL_SOURCE}) + COMMAND sed -i -b -e 's/pdFALSE/pdFAIL/g' -e 's/pdTRUE/pdPASS/g' ${FREERTOS_KERNEL_SOURCE} ${FREERTOS_PORT_CODE} + DEPENDS ${FREERTOS_KERNEL_SOURCE} ${FREERTOS_PORT_CODE}) # Add the freertos_config for FreeRTOS-Kernel. add_library(freertos_config INTERFACE) @@ -22,6 +23,12 @@ target_include_directories(freertos_config INTERFACE ./) +if (DEFINED FREERTOS_SMP_EXAMPLE AND FREERTOS_SMP_EXAMPLE STREQUAL "1") + message(STATUS "Build FreeRTOS SMP example") + # Adding the following configurations to build SMP template port + add_compile_options( -DconfigNUMBER_OF_CORES=2 -DconfigUSE_PASSIVE_IDLE_HOOK=0 ) +endif() + # Select the heap. Values between 1-5 will pick a heap. set(FREERTOS_HEAP "3" CACHE STRING "" FORCE) diff --git a/examples/coverity/FreeRTOSConfig.h b/examples/coverity/FreeRTOSConfig.h index 4d957872d..5feaa40de 100644 --- a/examples/coverity/FreeRTOSConfig.h +++ b/examples/coverity/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -118,7 +118,6 @@ #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskSuspend 1 -#define INCLUDE_xResumeFromISR 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 1 @@ -126,7 +125,6 @@ #define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_xTaskGetIdleTaskHandle 1 #define INCLUDE_eTaskGetState 1 -#define INCLUDE_xEventGroupSetBitFromISR 1 #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xTaskAbortDelay 1 #define INCLUDE_xTaskGetHandle 1 diff --git a/examples/coverity/README.md b/examples/coverity/README.md index 0daed7b22..60df69343 100644 --- a/examples/coverity/README.md +++ b/examples/coverity/README.md @@ -1,10 +1,10 @@ # MISRA Compliance for FreeRTOS-Kernel FreeRTOS-Kernel is MISRA C:2012 compliant. This directory contains a project to -run [Synopsys Coverity](https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html) +run [Synopsys Coverity](https://www.blackduck.com/static-analysis-tools-sast/coverity.html) for checking MISRA compliance. > **Note** -Coverity version 2022.6.1 incorrectly infers the type of `pdTRUE` and `pdFALSE` +Coverity version 2023.6.1 incorrectly infers the type of `pdTRUE` and `pdFALSE` as boolean because of their names, resulting in multiple false positive warnings about type mismatch. We replace `pdTRUE` with `pdPASS` and `pdFALSE` with `pdFAIL` to avoid these false positive warnings. This workaround will not be @@ -17,7 +17,7 @@ files. ## Getting Started ### Prerequisites -Coverity can be run on any platform mentioned [here](https://sig-docs.synopsys.com/polaris/topics/c_coverity-compatible-platforms.html). +Coverity can be run on any platform mentioned [here](https://documentation.blackduck.com/bundle/coverity-docs/page/deploy-install-guide/topics/supported_platforms_for_coverity_analysis.html). The following are the prerequisites to generate coverity report: 1. CMake version > 3.13.0 (You can check whether you have this by typing `cmake --version`). @@ -34,21 +34,27 @@ commands in a terminal: cov-configure --force --compiler cc --comptype gcc ~~~ 2. Create the build files using CMake in a `build` directory: + +Single core FreeRTOS: ~~~ cmake -B build -S examples/coverity ~~~ + +SMP FreeRTOS: + ~~~ + cmake -B build -S examples/coverity -DFREERTOS_SMP_EXAMPLE=1 + ~~~ 3. Build the (pseudo) application: ~~~ cd build/ - cov-build --emit-complementary-info --dir cov-out make + cov-build --emit-complementary-info --dir cov-out make coverity ~~~ 4. Go to the Coverity output directory (`cov-out`) and begin Coverity static analysis: ~~~ - cd cov-out/ cov-analyze --dir ./cov-out \ --coding-standard-config ../examples/coverity/coverity_misra.config \ - --tu-pattern "file('.*/FreeRTOS/Source/[A-Za-z_]*\.c') + --tu-pattern "file('[A-Za-z_]+\.c') && ( ! file('main.c') ) && ( ! file('port.c') )" ~~~ 5. Generate the HTML report: ~~~ diff --git a/examples/coverity/coverity_misra.config b/examples/coverity/coverity_misra.config index 101b20031..631142806 100644 --- a/examples/coverity/coverity_misra.config +++ b/examples/coverity/coverity_misra.config @@ -1,97 +1,95 @@ -// MISRA C-2012 Rules - { - version : "2.0", - standard : "c2012", - title: "Coverity MISRA Configuration", - deviations : [ - // Disable the following rules. + "version" : "2.0", + "standard" : "c2012", + "title": "Coverity MISRA Configuration", + "deviations" : [ { - deviation: "Rule 3.1", - reason: "We post HTTP links in code comments which contain // inside comments blocks." + "deviation": "Rule 1.2", + "reason": "Allow use of __attribute__ for necessary functions placement in specific memory regions." }, { - deviation: "Rule 14.4", - reason: "do while( 0 ) pattern is used in macros to prevent extra semi-colon." - }, - - // Disable the following advisory rules and directives. - { - deviation: "Directive 4.4", - reason: "Code snippet is used in comment to help explanation." + "deviation": "Rule 3.1", + "reason": "We post HTTP links in code comments which contain // inside comments blocks." }, { - deviation: "Directive 4.5", - reason: "Allow names that MISRA considers ambiguous." + "deviation": "Rule 14.4", + "reason": "do while( 0 ) pattern is used in macros to prevent extra semi-colon." }, { - deviation: "Directive 4.6", - reason: "Allow port to use primitive type with typedefs." + "deviation": "Directive 4.4", + "reason": "Code snippet is used in comment to help explanation." }, { - deviation: "Directive 4.8", - reason: "HeapRegion_t and HeapStats_t are used only in heap files but declared in portable.h which is included in multiple source files. As a result, these definitions appear in multiple source files where they are not used." + "deviation": "Directive 4.5", + "reason": "Allow names that MISRA considers ambiguous." }, { - deviation: "Directive 4.9", - reason: "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used." + "deviation": "Directive 4.6", + "reason": "Allow port to use primitive type with typedefs." }, { - deviation: "Rule 2.3", - reason: "FreeRTOS defines types which is used in application." + "deviation": "Directive 4.8", + "reason": "HeapRegion_t and HeapStats_t are used only in heap files but declared in portable.h which is included in multiple source files. As a result, these definitions appear in multiple source files where they are not used." }, { - deviation: "Rule 2.4", - reason: "Allow to define unused tag." + "deviation": "Directive 4.9", + "reason": "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used." }, { - deviation: "Rule 2.5", - reason: "Allow to define unused macro." + "deviation": "Rule 2.3", + "reason": "FreeRTOS defines types which is used in application." }, { - deviation: "Rule 5.9", - reason: "Allow to define identifier with the same name in structure and global variable." + "deviation": "Rule 2.4", + "reason": "Allow to define unused tag." }, { - deviation: "Rule 8.7", - reason: "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application." + "deviation": "Rule 2.5", + "reason": "Allow to define unused macro." }, { - deviation: "Rule 8.9", - reason: "Allow to object to be defined in wider scope for debug purpose." + "deviation": "Rule 5.9", + "reason": "Allow to define identifier with the same name in structure and global variable." }, { - deviation: "Rule 8.13", - reason: "Allow to not to use const-qualified type for callback function." + "deviation": "Rule 8.7", + "reason": "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application." }, { - deviation: "Rule 11.4", - reason: "Allow to convert between a pointer to object and an interger type for stack alignment." + "deviation": "Rule 8.9", + "reason": "Allow to object to be defined in wider scope for debug purpose." }, { - deviation: "Rule 15.4", - reason: "Allow to use multiple break statements in a loop." + "deviation": "Rule 8.13", + "reason": "Allow to not to use const-qualified type for callback function." }, { - deviation: "Rule 15.5", - reason: "Allow to use multiple points of exit." + "deviation": "Rule 11.4", + "reason": "Allow to convert between a pointer to object and an interger type for stack alignment." }, { - deviation: "Rule 17.8", - reason: "Allow to update the parameters of a function." + "deviation": "Rule 15.4", + "reason": "Allow to use multiple break statements in a loop." }, { - deviation: "Rule 18.4", - reason: "Allow to use pointer arithmetic." + "deviation": "Rule 15.5", + "reason": "Allow to use multiple points of exit." }, { - deviation: "Rule 19.2", - reason: "Allow to use union." + "deviation": "Rule 17.8", + "reason": "Allow to update the parameters of a function." }, { - deviation: "Rule 20.5", - reason: "Allow to use #undef for MPU wrappers." + "deviation": "Rule 18.4", + "reason": "Allow to use pointer arithmetic." + }, + { + "deviation": "Rule 19.2", + "reason": "Allow to use union." + }, + { + "deviation": "Rule 20.5", + "reason": "Allow to use #undef for MPU wrappers." } ] } - diff --git a/examples/template_configuration/FreeRTOSConfig.h b/examples/template_configuration/FreeRTOSConfig.h index a672600ff..5521adb4d 100644 --- a/examples/template_configuration/FreeRTOSConfig.h +++ b/examples/template_configuration/FreeRTOSConfig.h @@ -1,25 +1,26 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS @@ -47,10 +48,11 @@ /******************************************************************************/ /* In most cases, configCPU_CLOCK_HZ must be set to the frequency of the clock - * that drives the peripheral used to generate the kernels periodic tick interrupt. - * The default value is set to 20MHz and matches the QEMU demo settings. Your - * application will certainly need a different value so set this correctly. - * This is very often, but not always, equal to the main system clock frequency. */ + * that drives the peripheral used to generate the kernels periodic tick + * interrupt. The default value is set to 20MHz and matches the QEMU demo + * settings. Your application will certainly need a different value so set this + * correctly. This is very often, but not always, equal to the main system clock + * frequency. */ #define configCPU_CLOCK_HZ ( ( unsigned long ) 20000000 ) /* configSYSTICK_CLOCK_HZ is an optional parameter for ARM Cortex-M ports only. @@ -59,11 +61,11 @@ * Cortex-M SysTick timer. Most Cortex-M MCUs run the SysTick timer at the same * frequency as the MCU itself - when that is the case configSYSTICK_CLOCK_HZ is * not needed and should be left undefined. If the SysTick timer is clocked at a - * different frequency to the MCU core then set configCPU_CLOCK_HZ to the MCU clock - * frequency, as normal, and configSYSTICK_CLOCK_HZ to the SysTick clock + * different frequency to the MCU core then set configCPU_CLOCK_HZ to the MCU + * clock frequency, as normal, and configSYSTICK_CLOCK_HZ to the SysTick clock * frequency. Not used if left undefined. - * The default value is undefined (commented out). If you need this value bring it - * back and set it to a suitable value. */ + * The default value is undefined (commented out). If you need this value bring + * it back and set it to a suitable value. */ /* #define configSYSTICK_CLOCK_HZ [Platform specific] @@ -90,28 +92,29 @@ #define configUSE_TIME_SLICING 0 /* Set configUSE_PORT_OPTIMISED_TASK_SELECTION to 1 to select the next task to - * run using an algorithm optimised to the instruction set of the target hardware - - * normally using a count leading zeros assembly instruction. Set to 0 to select - * the next task to run using a generic C algorithm that works for all FreeRTOS - * ports. Not all FreeRTOS ports have this option. Defaults to 0 if left - * undefined. */ + * run using an algorithm optimised to the instruction set of the target + * hardware - normally using a count leading zeros assembly instruction. Set to + * 0 to select the next task to run using a generic C algorithm that works for + * all FreeRTOS ports. Not all FreeRTOS ports have this option. Defaults to 0 + * if left undefined. */ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 /* Set configUSE_TICKLESS_IDLE to 1 to use the low power tickless mode. Set to * 0 to keep the tick interrupt running at all times. Not all FreeRTOS ports - * support tickless mode. See https://www.freertos.org/low-power-tickless-rtos.html - * Defaults to 0 if left undefined. */ + * support tickless mode. See + * https://www.freertos.org/low-power-tickless-rtos.html Defaults to 0 if left + * undefined. */ #define configUSE_TICKLESS_IDLE 0 /* configMAX_PRIORITIES Sets the number of available task priorities. Tasks can - * be assigned priorities of 0 to (configMAX_PRIORITIES - 1). Zero is the lowest - * priority. */ + * be assigned priorities of 0 to (configMAX_PRIORITIES - 1). Zero is the + * lowest priority. */ #define configMAX_PRIORITIES 5 /* configMINIMAL_STACK_SIZE defines the size of the stack used by the Idle task - * (in words, not in bytes!). The kernel does not use this constant for any other - * purpose. Demo applications use the constant to make the demos somewhat portable - * across hardware architectures. */ + * (in words, not in bytes!). The kernel does not use this constant for any + * other purpose. Demo applications use the constant to make the demos somewhat + * portable across hardware architectures. */ #define configMINIMAL_STACK_SIZE 128 /* configMAX_TASK_NAME_LEN sets the maximum length (in characters) of a task's @@ -122,7 +125,8 @@ * has executed since the RTOS kernel was started. * The tick count is held in a variable of type TickType_t. * - * configTICK_TYPE_WIDTH_IN_BITS controls the type (and therefore bit-width) of TickType_t: + * configTICK_TYPE_WIDTH_IN_BITS controls the type (and therefore bit-width) of + * TickType_t: * * Defining configTICK_TYPE_WIDTH_IN_BITS as TICK_TYPE_WIDTH_16_BITS causes * TickType_t to be defined (typedef'ed) as an unsigned 16-bit type. @@ -135,15 +139,15 @@ #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_64_BITS /* Set configIDLE_SHOULD_YIELD to 1 to have the Idle task yield to an - * application task if there is an Idle priority (priority 0) application task that - * can run. Set to 0 to have the Idle task use all of its timeslice. Default to 1 - * if left undefined. */ + * application task if there is an Idle priority (priority 0) application task + * that can run. Set to 0 to have the Idle task use all of its timeslice. + * Default to 1 if left undefined. */ #define configIDLE_SHOULD_YIELD 1 /* Each task has an array of task notifications. - * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the array. - * See https://www.freertos.org/RTOS-task-notifications.html Defaults to 1 if - * left undefined. */ + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array. See https://www.freertos.org/RTOS-task-notifications.html Defaults to + * 1 if left undefined. */ #define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 /* configQUEUE_REGISTRY_SIZE sets the maximum number of queues and semaphores @@ -152,21 +156,22 @@ #define configQUEUE_REGISTRY_SIZE 0 /* Set configENABLE_BACKWARD_COMPATIBILITY to 1 to map function names and - * datatypes from old version of FreeRTOS to their latest equivalent. Defaults to - * 1 if left undefined. */ + * datatypes from old version of FreeRTOS to their latest equivalent. Defaults + * to 1 if left undefined. */ #define configENABLE_BACKWARD_COMPATIBILITY 0 /* Each task has its own array of pointers that can be used as thread local - * storage. configNUM_THREAD_LOCAL_STORAGE_POINTERS set the number of indexes in - * the array. See https://www.freertos.org/thread-local-storage-pointers.html - * Defaults to 0 if left undefined. */ + * storage. configNUM_THREAD_LOCAL_STORAGE_POINTERS set the number of indexes + * in the array. See + * https://www.freertos.org/thread-local-storage-pointers.html Defaults to 0 if + * left undefined. */ #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 /* When configUSE_MINI_LIST_ITEM is set to 0, MiniListItem_t and ListItem_t are - * both the same. When configUSE_MINI_LIST_ITEM is set to 1, MiniListItem_t contains - * 3 fewer fields than ListItem_t which saves some RAM at the cost of violating - * strict aliasing rules which some compilers depend on for optimization. Defaults - * to 1 if left undefined. */ + * both the same. When configUSE_MINI_LIST_ITEM is set to 1, MiniListItem_t + * contains 3 fewer fields than ListItem_t which saves some RAM at the cost of + * violating strict aliasing rules which some compilers depend on for + * optimization. Defaults to 1 if left undefined. */ #define configUSE_MINI_LIST_ITEM 1 /* Sets the type used by the parameter to xTaskCreate() that specifies the stack @@ -176,22 +181,22 @@ #define configSTACK_DEPTH_TYPE size_t /* configMESSAGE_BUFFER_LENGTH_TYPE sets the type used to store the length of - * each message written to a FreeRTOS message buffer (the length is also written to - * the message buffer. Defaults to size_t if left undefined - but that may waste - * space if messages never go above a length that could be held in a uint8_t. */ + * each message written to a FreeRTOS message buffer (the length is also written + * to the message buffer. Defaults to size_t if left undefined - but that may + * waste space if messages never go above a length that could be held in a + * uint8_t. */ #define configMESSAGE_BUFFER_LENGTH_TYPE size_t -/* If configHEAP_CLEAR_MEMORY_ON_FREE is set to 1, then blocks of memory allocated - * using pvPortMalloc() will be cleared (i.e. set to zero) when freed using - * vPortFree(). Defaults to 0 if left undefined. */ +/* If configHEAP_CLEAR_MEMORY_ON_FREE is set to 1, then blocks of memory + * allocated using pvPortMalloc() will be cleared (i.e. set to zero) when freed + * using vPortFree(). Defaults to 0 if left undefined. */ #define configHEAP_CLEAR_MEMORY_ON_FREE 1 -/* vTaskList and vTaskGetRunTimeStats APIs take a buffer as a parameter and assume - * that the length of the buffer is configSTATS_BUFFER_MAX_LENGTH. Defaults to - * 0xFFFF if left undefined. - * New applications are recommended to use vTaskListTasks and - * vTaskGetRunTimeStatistics APIs instead and supply the length of the buffer - * explicitly to avoid memory corruption. */ +/* vTaskList and vTaskGetRunTimeStats APIs take a buffer as a parameter and + * assume that the length of the buffer is configSTATS_BUFFER_MAX_LENGTH. + * Defaults to 0xFFFF if left undefined. New applications are recommended to use + * vTaskListTasks and vTaskGetRunTimeStatistics APIs instead and supply the + * length of the buffer explicitly to avoid memory corruption. */ #define configSTATS_BUFFER_MAX_LENGTH 0xFFFF /* Set configUSE_NEWLIB_REENTRANT to 1 to have a newlib reent structure @@ -199,11 +204,11 @@ * Default to 0 if left undefined. * * Note Newlib support has been included by popular demand, but is not used or - * tested by the FreeRTOS maintainers themselves. FreeRTOS is not responsible for - * resulting newlib operation. User must be familiar with newlib and must provide - * system-wide implementations of the necessary stubs. Note that (at the time of - * writing) the current newlib design implements a system-wide malloc() that must - * be provided with locks. */ + * tested by the FreeRTOS maintainers themselves. FreeRTOS is not responsible + * for resulting newlib operation. User must be familiar with newlib and must + * provide system-wide implementations of the necessary stubs. Note that (at the + * time of writing) the current newlib design implements a system-wide malloc() + * that must be provided with locks. */ #define configUSE_NEWLIB_REENTRANT 0 /******************************************************************************/ @@ -220,22 +225,45 @@ /* configTIMER_TASK_PRIORITY sets the priority used by the timer task. Only * used if configUSE_TIMERS is set to 1. The timer task is a standard FreeRTOS * task, so its priority is set like any other task. See - * https://www.freertos.org/RTOS-software-timer-service-daemon-task.html Only used - * if configUSE_TIMERS is set to 1. */ + * https://www.freertos.org/RTOS-software-timer-service-daemon-task.html Only + * used if configUSE_TIMERS is set to 1. */ #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) /* configTIMER_TASK_STACK_DEPTH sets the size of the stack allocated to the * timer task (in words, not in bytes!). The timer task is a standard FreeRTOS - * task. See https://www.freertos.org/RTOS-software-timer-service-daemon-task.html - * Only used if configUSE_TIMERS is set to 1. */ + * task. See + * https://www.freertos.org/RTOS-software-timer-service-daemon-task.html Only + * used if configUSE_TIMERS is set to 1. */ #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* configTIMER_QUEUE_LENGTH sets the length of the queue (the number of discrete * items the queue can hold) used to send commands to the timer task. See - * https://www.freertos.org/RTOS-software-timer-service-daemon-task.html Only used - * if configUSE_TIMERS is set to 1. */ + * https://www.freertos.org/RTOS-software-timer-service-daemon-task.html Only + * used if configUSE_TIMERS is set to 1. */ #define configTIMER_QUEUE_LENGTH 10 +/******************************************************************************/ +/* Event Group related definitions. *******************************************/ +/******************************************************************************/ + +/* Set configUSE_EVENT_GROUPS to 1 to include event group functionality in the + * build. Set to 0 to exclude event group functionality from the build. The + * FreeRTOS/source/event_groups.c source file must be included in the build if + * configUSE_EVENT_GROUPS is set to 1. Defaults to 1 if left undefined. */ + +#define configUSE_EVENT_GROUPS 1 + +/******************************************************************************/ +/* Stream Buffer related definitions. *****************************************/ +/******************************************************************************/ + +/* Set configUSE_STREAM_BUFFERS to 1 to include stream buffer functionality in + * the build. Set to 0 to exclude event group functionality from the build. The + * FreeRTOS/source/stream_buffer.c source file must be included in the build if + * configUSE_STREAM_BUFFERS is set to 1. Defaults to 1 if left undefined. */ + +#define configUSE_STREAM_BUFFERS 1 + /******************************************************************************/ /* Memory allocation related definitions. *************************************/ /******************************************************************************/ @@ -248,21 +276,22 @@ #define configSUPPORT_STATIC_ALLOCATION 1 /* Set configSUPPORT_DYNAMIC_ALLOCATION to 1 to include FreeRTOS API functions - * that create FreeRTOS objects (tasks, queues, etc.) using dynamically allocated - * memory in the build. Set to 0 to exclude the ability to create dynamically - * allocated objects from the build. Defaults to 1 if left undefined. See + * that create FreeRTOS objects (tasks, queues, etc.) using dynamically + * allocated memory in the build. Set to 0 to exclude the ability to create + * dynamically allocated objects from the build. Defaults to 1 if left + * undefined. See * https://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html. */ #define configSUPPORT_DYNAMIC_ALLOCATION 1 /* Sets the total size of the FreeRTOS heap, in bytes, when heap_1.c, heap_2.c - * or heap_4.c are included in the build. This value is defaulted to 4096 bytes but - * it must be tailored to each application. Note the heap will appear in the .bss - * section. See https://www.freertos.org/a00111.html. */ + * or heap_4.c are included in the build. This value is defaulted to 4096 bytes + * but it must be tailored to each application. Note the heap will appear in + * the .bss section. See https://www.freertos.org/a00111.html. */ #define configTOTAL_HEAP_SIZE 4096 /* Set configAPPLICATION_ALLOCATED_HEAP to 1 to have the application allocate - * the array used as the FreeRTOS heap. Set to 0 to have the linker allocate the - * array used as the FreeRTOS heap. Defaults to 0 if left undefined. */ + * the array used as the FreeRTOS heap. Set to 0 to have the linker allocate + * the array used as the FreeRTOS heap. Defaults to 0 if left undefined. */ #define configAPPLICATION_ALLOCATED_HEAP 0 /* Set configSTACK_ALLOCATION_FROM_SEPARATE_HEAP to 1 to have task stacks @@ -273,9 +302,9 @@ * Defaults to 0 if left undefined. */ #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -/* Set configENABLE_HEAP_PROTECTOR to 1 to enable bounds checking and obfuscation - * to internal heap block pointers in heap_4.c and heap_5.c to help catch pointer - * corruptions. Defaults to 0 if left undefined. */ +/* Set configENABLE_HEAP_PROTECTOR to 1 to enable bounds checking and + * obfuscation to internal heap block pointers in heap_4.c and heap_5.c to help + * catch pointer corruptions. Defaults to 0 if left undefined. */ #define configENABLE_HEAP_PROTECTOR 0 /******************************************************************************/ @@ -283,18 +312,17 @@ /******************************************************************************/ /* configKERNEL_INTERRUPT_PRIORITY sets the priority of the tick and context - * switch performing interrupts. The default value is set to the highest interrupt - * priority (0). Not supported by all FreeRTOS ports. See - * https://www.freertos.org/RTOS-Cortex-M3-M4.html for information specific to ARM - * Cortex-M devices. */ + * switch performing interrupts. Not supported by all FreeRTOS ports. See + * https://www.freertos.org/RTOS-Cortex-M3-M4.html for information specific to + * ARM Cortex-M devices. */ #define configKERNEL_INTERRUPT_PRIORITY 0 /* configMAX_SYSCALL_INTERRUPT_PRIORITY sets the interrupt priority above which - * FreeRTOS API calls must not be made. Interrupts above this priority are never - * disabled, so never delayed by RTOS activity. The default value is set to the - * highest interrupt priority (0). Not supported by all FreeRTOS ports. - * See https://www.freertos.org/RTOS-Cortex-M3-M4.html for information specific to - * ARM Cortex-M devices. */ + * FreeRTOS API calls must not be made. Interrupts above this priority are + * never disabled, so never delayed by RTOS activity. The default value is set + * to the highest interrupt priority (0). Not supported by all FreeRTOS ports. + * See https://www.freertos.org/RTOS-Cortex-M3-M4.html for information specific + * to ARM Cortex-M devices. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY 0 /* Another name for configMAX_SYSCALL_INTERRUPT_PRIORITY - the name used depends @@ -306,9 +334,9 @@ /******************************************************************************/ /* Set the following configUSE_* constants to 1 to include the named hook - * functionality in the build. Set to 0 to exclude the hook functionality from the - * build. The application writer is responsible for providing the hook function - * for any set to 1. See https://www.freertos.org/a00016.html. */ + * functionality in the build. Set to 0 to exclude the hook functionality from + * the build. The application writer is responsible for providing the hook + * function for any set to 1. See https://www.freertos.org/a00016.html. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 @@ -325,14 +353,15 @@ /* Set configCHECK_FOR_STACK_OVERFLOW to 1 or 2 for FreeRTOS to check for a * stack overflow at the time of a context switch. Set to 0 to not look for a * stack overflow. If configCHECK_FOR_STACK_OVERFLOW is 1 then the check only - * looks for the stack pointer being out of bounds when a task's context is saved - * to its stack - this is fast but somewhat ineffective. If - * configCHECK_FOR_STACK_OVERFLOW is 2 then the check looks for a pattern written - * to the end of a task's stack having been overwritten. This is slower, but will - * catch most (but not all) stack overflows. The application writer must provide - * the stack overflow callback when configCHECK_FOR_STACK_OVERFLOW is set to 1. - * See https://www.freertos.org/Stacks-and-stack-overflow-checking.html Defaults - * to 0 if left undefined. */ + * looks for the stack pointer being out of bounds when a task's context is + * saved to its stack - this is fast but somewhat ineffective. If + * configCHECK_FOR_STACK_OVERFLOW is 2 then the check looks for a pattern + * written to the end of a task's stack having been overwritten. This is + * slower, but will catch most (but not all) stack overflows. The application + * writer must provide the stack overflow callback when + * configCHECK_FOR_STACK_OVERFLOW is set to 1. See + * https://www.freertos.org/Stacks-and-stack-overflow-checking.html Defaults to + * 0 if left undefined. */ #define configCHECK_FOR_STACK_OVERFLOW 2 /******************************************************************************/ @@ -341,8 +370,9 @@ /* Set configGENERATE_RUN_TIME_STATS to 1 to have FreeRTOS collect data on the * processing time used by each task. Set to 0 to not collect the data. The - * application writer needs to provide a clock source if set to 1. Defaults to 0 - * if left undefined. See https://www.freertos.org/rtos-run-time-stats.html. */ + * application writer needs to provide a clock source if set to 1. Defaults to + * 0 if left undefined. See https://www.freertos.org/rtos-run-time-stats.html. + */ #define configGENERATE_RUN_TIME_STATS 0 /* Set configUSE_TRACE_FACILITY to include additional task structure members @@ -364,8 +394,8 @@ /* Set configUSE_CO_ROUTINES to 1 to include co-routine functionality in the * build, or 0 to omit co-routine functionality from the build. To include - * co-routines, croutine.c must be included in the project. Defaults to 0 if left - * undefined. */ + * co-routines, croutine.c must be included in the project. Defaults to 0 if + * left undefined. */ #define configUSE_CO_ROUTINES 0 /* configMAX_CO_ROUTINE_PRIORITIES defines the number of priorities available @@ -382,9 +412,11 @@ * at all (i.e. comment out or delete the definitions) to completely remove * assertions. configASSERT() can be defined to anything you want, for example * you can call a function if an assert fails that passes the filename and line - * 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. */ + * 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 ) \ { \ @@ -392,6 +424,7 @@ for( ; ; ) \ ; \ } +/* *INDENT-ON* */ /******************************************************************************/ /* FreeRTOS MPU specific definitions. *****************************************/ @@ -399,9 +432,10 @@ /* If configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS is set to 1 then * the application writer can provide functions that execute in privileged mode. - * See: https://www.freertos.org/a00110.html#configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS - * Defaults to 0 if left undefined. Only used by the FreeRTOS Cortex-M MPU ports, - * not the standard ARMv7-M Cortex-M port. */ + * See: + * https://www.freertos.org/a00110.html#configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + * Defaults to 0 if left undefined. Only used by the FreeRTOS Cortex-M MPU + * ports, not the standard ARMv7-M Cortex-M port. */ #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 /* Set configTOTAL_MPU_REGIONS to the number of MPU regions implemented on your @@ -411,28 +445,28 @@ #define configTOTAL_MPU_REGIONS 8 /* configTEX_S_C_B_FLASH allows application writers to override the default - * values for the for TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for - * the MPU region covering Flash. Defaults to 0x07UL (which means TEX=000, S=1, - * C=1, B=1) if left undefined. Only used by the FreeRTOS Cortex-M MPU ports, not - * the standard ARMv7-M Cortex-M port. */ + * values for the for TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits + * for the MPU region covering Flash. Defaults to 0x07UL (which means TEX=000, + * S=1, C=1, B=1) if left undefined. Only used by the FreeRTOS Cortex-M MPU + * ports, not the standard ARMv7-M Cortex-M port. */ #define configTEX_S_C_B_FLASH 0x07UL /* configTEX_S_C_B_SRAM allows application writers to override the default - * values for the for TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for - * the MPU region covering RAM. Defaults to 0x07UL (which means TEX=000, S=1, C=1, - * B=1) if left undefined. Only used by the FreeRTOS Cortex-M MPU ports, not - * the standard ARMv7-M Cortex-M port. */ + * values for the for TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits + * for the MPU region covering RAM. Defaults to 0x07UL (which means TEX=000, + * S=1, C=1, B=1) if left undefined. Only used by the FreeRTOS Cortex-M MPU + * ports, not the standard ARMv7-M Cortex-M port. */ #define configTEX_S_C_B_SRAM 0x07UL /* Set configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY to 0 to prevent any privilege * escalations originating from outside of the kernel code itself. Set to 1 to * allow application tasks to raise privilege. Defaults to 1 if left undefined. - * Only used by the FreeRTOS Cortex-M MPU ports, not the standard ARMv7-M Cortex-M - * port. */ + * Only used by the FreeRTOS Cortex-M MPU ports, not the standard ARMv7-M + * Cortex-M port. */ #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1 /* Set configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS to 1 to allow unprivileged - * tasks enter critical sections (effectively mask interrupts). Set to 0 to + * tasks enter critical sections (effectively mask interrupts). Set to 0 to * prevent unprivileged tasks entering critical sections. Defaults to 1 if left * undefined. Only used by the FreeRTOS Cortex-M MPU ports, not the standard * ARMv7-M Cortex-M port. */ @@ -472,8 +506,8 @@ /* SMP( Symmetric MultiProcessing ) Specific Configuration definitions. *******/ /******************************************************************************/ -/* Set configNUMBER_OF_CORES to the number of available processor cores. Defaults - * to 1 if left undefined. */ +/* Set configNUMBER_OF_CORES to the number of available processor cores. + * Defaults to 1 if left undefined. */ /* #define configNUMBER_OF_CORES [Num of available cores] @@ -490,12 +524,22 @@ /* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), set * configUSE_CORE_AFFINITY to 1 to enable core affinity feature. When core - * affinity feature is enabled, the vTaskCoreAffinitySet and vTaskCoreAffinityGet - * APIs can be used to set and retrieve which cores a task can run on. If - * configUSE_CORE_AFFINITY is set to 0 then the FreeRTOS scheduler is free to - * run any task on any available core. */ + * affinity feature is enabled, the vTaskCoreAffinitySet and + * vTaskCoreAffinityGet APIs can be used to set and retrieve which cores a task + * can run on. If configUSE_CORE_AFFINITY is set to 0 then the FreeRTOS + * scheduler is free to run any task on any available core. */ #define configUSE_CORE_AFFINITY 0 +/* When using SMP with core affinity feature enabled, set + * configTASK_DEFAULT_CORE_AFFINITY to change the default core affinity mask for + * tasks created without an affinity mask specified. Setting the define to 1 + * would make such tasks run on core 0 and setting it to (1 << + * portGET_CORE_ID()) would make such tasks run on the current core. This config + * value is useful, if swapping tasks between cores is not supported (e.g. + * Tricore) or if legacy code should be controlled. Defaults to tskNO_AFFINITY + * if left undefined. */ +#define configTASK_DEFAULT_CORE_AFFINITY tskNO_AFFINITY + /* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), if * configUSE_TASK_PREEMPTION_DISABLE is set to 1, individual tasks can be set to * either pre-emptive or co-operative mode using the vTaskPreemptionDisable and @@ -504,8 +548,8 @@ /* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), set * configUSE_PASSIVE_IDLE_HOOK to 1 to allow the application writer to use - * the passive idle task hook to add background functionality without the overhead - * of a separate task. Defaults to 0 if left undefined. */ + * the passive idle task hook to add background functionality without the + * overhead of a separate task. Defaults to 0 if left undefined. */ #define configUSE_PASSIVE_IDLE_HOOK 0 /* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), @@ -514,23 +558,77 @@ * tskNO_AFFINITY if left undefined. */ #define configTIMER_SERVICE_TASK_CORE_AFFINITY tskNO_AFFINITY - /******************************************************************************/ /* ARMv8-M secure side port related definitions. ******************************/ /******************************************************************************/ /* secureconfigMAX_SECURE_CONTEXTS define the maximum number of tasks that can - * call into the secure side of an ARMv8-M chip. Not used by any other ports. */ + * call into the secure side of an ARMv8-M chip. Not used by any other ports. + */ #define secureconfigMAX_SECURE_CONTEXTS 5 /* Defines the kernel provided implementation of * vApplicationGetIdleTaskMemory() and vApplicationGetTimerTaskMemory() - * to provide the memory that is used by the Idle task and Timer task respectively. - * The application can provide it's own implementation of + * to provide the memory that is used by the Idle task and Timer task + * respectively. The application can provide it's own implementation of * vApplicationGetIdleTaskMemory() and vApplicationGetTimerTaskMemory() by * setting configKERNEL_PROVIDED_STATIC_MEMORY to 0 or leaving it undefined. */ #define configKERNEL_PROVIDED_STATIC_MEMORY 1 +/******************************************************************************/ +/* ARMv8-M port Specific Configuration definitions. ***************************/ +/******************************************************************************/ + +/* Set configENABLE_TRUSTZONE to 1 when running FreeRTOS on the non-secure side + * to enable the TrustZone support in FreeRTOS ARMv8-M ports which allows the + * non-secure FreeRTOS tasks to call the (non-secure callable) functions + * exported from secure side. */ +#define configENABLE_TRUSTZONE 1 + +/* If the application writer does not want to use TrustZone, but the hardware + * does not support disabling TrustZone then the entire application (including + * the FreeRTOS scheduler) can run on the secure side without ever branching to + * the non-secure side. To do that, in addition to setting + * configENABLE_TRUSTZONE to 0, also set configRUN_FREERTOS_SECURE_ONLY to 1. */ +#define configRUN_FREERTOS_SECURE_ONLY 1 + +/* Set configENABLE_MPU to 1 to enable the Memory Protection Unit (MPU), or 0 + * to leave the Memory Protection Unit disabled. */ +#define configENABLE_MPU 1 + +/* Set configENABLE_FPU to 1 to enable the Floating Point Unit (FPU), or 0 + * to leave the Floating Point Unit disabled. */ +#define configENABLE_FPU 1 + +/* Set configENABLE_MVE to 1 to enable the M-Profile Vector Extension (MVE) + * support, or 0 to leave the MVE support disabled. This option is only + * applicable to Cortex-M55 and Cortex-M85 ports as M-Profile Vector Extension + * (MVE) is available only on these architectures. configENABLE_MVE must be left + * undefined, or defined to 0 for the Cortex-M23,Cortex-M33 and Cortex-M35P + * ports. */ +#define configENABLE_MVE 1 + +/******************************************************************************/ +/* ARMv7-M and ARMv8-M port Specific Configuration definitions. ***************/ +/******************************************************************************/ + +/* Set configCHECK_HANDLER_INSTALLATION to 1 to enable additional asserts to + * verify that the application has correctly installed FreeRTOS interrupt + * handlers. + * + * An application can install FreeRTOS interrupt handlers in one of the + * following ways: + * 1. Direct Routing - Install the functions vPortSVCHandler and + * xPortPendSVHandler for SVC call and PendSV interrupts respectively. + * 2. Indirect Routing - Install separate handlers for SVC call and PendSV + * interrupts and route program control from those + * handlers to vPortSVCHandler and xPortPendSVHandler functions. The + * applications that use Indirect Routing must set + * configCHECK_HANDLER_INSTALLATION to 0. + * + * Defaults to 1 if left undefined. */ +#define configCHECK_HANDLER_INSTALLATION 1 + /******************************************************************************/ /* Definitions that include or exclude functionality. *************************/ /******************************************************************************/ @@ -544,14 +642,17 @@ #define configUSE_QUEUE_SETS 0 #define configUSE_APPLICATION_TASK_TAG 0 -/* Set the following INCLUDE_* constants to 1 to incldue the named API function, +/* USE_POSIX_ERRNO enables the task global FreeRTOS_errno variable which will + * contain the most recent error for that task. */ +#define configUSE_POSIX_ERRNO 0 + +/* Set the following INCLUDE_* constants to 1 to include the named API function, * or 0 to exclude the named API function. Most linkers will remove unused * functions even when the constant is 1. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskSuspend 1 -#define INCLUDE_xResumeFromISR 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 1 @@ -559,7 +660,6 @@ #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_eTaskGetState 0 -#define INCLUDE_xEventGroupSetBitFromISR 1 #define INCLUDE_xTimerPendFunctionCall 0 #define INCLUDE_xTaskAbortDelay 0 #define INCLUDE_xTaskGetHandle 0 diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 23526bb02..63e2feb51 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -49,12 +49,6 @@ */ #include /* READ COMMENT ABOVE. */ -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - /* Acceptable values for configTICK_TYPE_WIDTH_IN_BITS. */ #define TICK_TYPE_WIDTH_16_BITS 0 #define TICK_TYPE_WIDTH_32_BITS 1 @@ -96,6 +90,27 @@ #define configNUMBER_OF_CORES 1 #endif +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #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" @@ -125,6 +140,12 @@ #endif /* if ( configUSE_PICOLIBC_TLS == 1 ) */ +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + #ifndef configUSE_C_RUNTIME_TLS_SUPPORT #define configUSE_C_RUNTIME_TLS_SUPPORT 0 #endif @@ -294,10 +315,6 @@ #endif #endif -#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK - #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 -#endif - #ifndef configUSE_APPLICATION_TASK_TAG #define configUSE_APPLICATION_TASK_TAG 0 #endif @@ -318,6 +335,24 @@ #define configUSE_TIMERS 0 #endif +#ifndef configUSE_EVENT_GROUPS + #define configUSE_EVENT_GROUPS 1 +#endif + +#ifndef configUSE_STREAM_BUFFERS + #define configUSE_STREAM_BUFFERS 1 +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#if ( configUSE_DAEMON_TASK_STARTUP_HOOK != 0 ) + #if ( configUSE_TIMERS == 0 ) + #error configUSE_DAEMON_TASK_STARTUP_HOOK is set, but the daemon task is not created because configUSE_TIMERS is 0. + #endif +#endif + #ifndef configUSE_COUNTING_SEMAPHORES #define configUSE_COUNTING_SEMAPHORES 0 #endif @@ -346,13 +381,6 @@ #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h #endif -#ifndef configASSERT - #define configASSERT( x ) - #define configASSERT_DEFINED 0 -#else - #define configASSERT_DEFINED 1 -#endif - /* configPRECONDITION should be defined as configASSERT. * The CBMC proofs need a way to track assumptions and assertions. * A configPRECONDITION statement should express an implicit invariant or @@ -427,7 +455,7 @@ #ifndef portRELEASE_TASK_LOCK #if ( configNUMBER_OF_CORES == 1 ) - #define portRELEASE_TASK_LOCK() + #define portRELEASE_TASK_LOCK( xCoreID ) #else #error portRELEASE_TASK_LOCK is required in SMP #endif @@ -437,7 +465,7 @@ #ifndef portGET_TASK_LOCK #if ( configNUMBER_OF_CORES == 1 ) - #define portGET_TASK_LOCK() + #define portGET_TASK_LOCK( xCoreID ) #else #error portGET_TASK_LOCK is required in SMP #endif @@ -447,7 +475,7 @@ #ifndef portRELEASE_ISR_LOCK #if ( configNUMBER_OF_CORES == 1 ) - #define portRELEASE_ISR_LOCK() + #define portRELEASE_ISR_LOCK( xCoreID ) #else #error portRELEASE_ISR_LOCK is required in SMP #endif @@ -457,7 +485,7 @@ #ifndef portGET_ISR_LOCK #if ( configNUMBER_OF_CORES == 1 ) - #define portGET_ISR_LOCK() + #define portGET_ISR_LOCK( xCoreID ) #else #error portGET_ISR_LOCK is required in SMP #endif @@ -484,6 +512,12 @@ #define configUSE_CORE_AFFINITY 0 #endif /* configUSE_CORE_AFFINITY */ +#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) + #ifndef configTASK_DEFAULT_CORE_AFFINITY + #define configTASK_DEFAULT_CORE_AFFINITY tskNO_AFFINITY + #endif +#endif + #ifndef configUSE_PASSIVE_IDLE_HOOK #define configUSE_PASSIVE_IDLE_HOOK 0 #endif /* configUSE_PASSIVE_IDLE_HOOK */ @@ -509,12 +543,36 @@ #endif /* configUSE_TIMERS */ +#ifndef portHAS_NESTED_INTERRUPTS + #if defined( portSET_INTERRUPT_MASK_FROM_ISR ) && defined( portCLEAR_INTERRUPT_MASK_FROM_ISR ) + #define portHAS_NESTED_INTERRUPTS 1 + #else + #define portHAS_NESTED_INTERRUPTS 0 + #endif +#endif + #ifndef portSET_INTERRUPT_MASK_FROM_ISR - #define portSET_INTERRUPT_MASK_FROM_ISR() 0 + #if ( portHAS_NESTED_INTERRUPTS == 1 ) + #error portSET_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1) + #else + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 + #endif +#else + #if ( portHAS_NESTED_INTERRUPTS == 0 ) + #error portSET_INTERRUPT_MASK_FROM_ISR must not be defined for ports that do not support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0) + #endif #endif #ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue ) + #if ( portHAS_NESTED_INTERRUPTS == 1 ) + #error portCLEAR_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1) + #else + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue ) + #endif +#else + #if ( portHAS_NESTED_INTERRUPTS == 0 ) + #error portCLEAR_INTERRUPT_MASK_FROM_ISR must not be defined for ports that do not support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0) + #endif #endif #ifndef portCLEAN_UP_TCB @@ -573,6 +631,13 @@ #define traceTASK_SWITCHED_IN() #endif +#ifndef traceSTARTING_SCHEDULER + +/* Called after all idle tasks and timer task (if enabled) have been created + * successfully, just before the scheduler is started. */ + #define traceSTARTING_SCHEDULER( xIdleTaskHandles ) +#endif + #ifndef traceINCREASE_TICK_COUNT /* Called before stepping the tick count after waking from tickless idle @@ -934,15 +999,15 @@ #endif #ifndef traceSTREAM_BUFFER_CREATE_FAILED - #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) + #define traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType ) #endif #ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED - #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType ) #endif #ifndef traceSTREAM_BUFFER_CREATE - #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xStreamBufferType ) #endif #ifndef traceSTREAM_BUFFER_DELETE @@ -953,6 +1018,10 @@ #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) #endif +#ifndef traceSTREAM_BUFFER_RESET_FROM_ISR + #define traceSTREAM_BUFFER_RESET_FROM_ISR( xStreamBuffer ) +#endif + #ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) #endif @@ -1425,6 +1494,14 @@ #define traceRETURN_xQueueCreateSet( pxQueue ) #endif +#ifndef traceENTER_xQueueCreateSetStatic + #define traceENTER_xQueueCreateSetStatic( uxEventQueueLength ) +#endif + +#ifndef traceRETURN_xQueueCreateSetStatic + #define traceRETURN_xQueueCreateSetStatic( pxQueue ) +#endif + #ifndef traceENTER_xQueueAddToSet #define traceENTER_xQueueAddToSet( xQueueOrSemaphore, xQueueSet ) #endif @@ -1618,7 +1695,7 @@ #endif #ifndef traceENTER_xTaskCreateStatic - #define traceENTER_xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ) + #define traceENTER_xTaskCreateStatic( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ) #endif #ifndef traceRETURN_xTaskCreateStatic @@ -1626,7 +1703,7 @@ #endif #ifndef traceENTER_xTaskCreateStaticAffinitySet - #define traceENTER_xTaskCreateStaticAffinitySet( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask ) + #define traceENTER_xTaskCreateStaticAffinitySet( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask ) #endif #ifndef traceRETURN_xTaskCreateStaticAffinitySet @@ -1666,7 +1743,7 @@ #endif #ifndef traceENTER_xTaskCreate - #define traceENTER_xTaskCreate( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) + #define traceENTER_xTaskCreate( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask ) #endif #ifndef traceRETURN_xTaskCreate @@ -1674,7 +1751,7 @@ #endif #ifndef traceENTER_xTaskCreateAffinitySet - #define traceENTER_xTaskCreateAffinitySet( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask ) + #define traceENTER_xTaskCreateAffinitySet( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask ) #endif #ifndef traceRETURN_xTaskCreateAffinitySet @@ -2350,7 +2427,7 @@ #endif #ifndef traceENTER_xStreamBufferGenericCreate - #define traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) + #define traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pxSendCompletedCallback, pxReceiveCompletedCallback ) #endif #ifndef traceRETURN_xStreamBufferGenericCreate @@ -2358,7 +2435,7 @@ #endif #ifndef traceENTER_xStreamBufferGenericCreateStatic - #define traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) + #define traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) #endif #ifndef traceRETURN_xStreamBufferGenericCreateStatic @@ -2389,6 +2466,14 @@ #define traceRETURN_xStreamBufferReset( xReturn ) #endif +#ifndef traceENTER_xStreamBufferResetFromISR + #define traceENTER_xStreamBufferResetFromISR( xStreamBuffer ) +#endif + +#ifndef traceRETURN_xStreamBufferResetFromISR + #define traceRETURN_xStreamBufferResetFromISR( xReturn ) +#endif + #ifndef traceENTER_xStreamBufferSetTriggerLevel #define traceENTER_xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ) #endif @@ -2485,6 +2570,22 @@ #define traceRETURN_xStreamBufferReceiveCompletedFromISR( xReturn ) #endif +#ifndef traceENTER_uxStreamBufferGetStreamBufferNotificationIndex + #define traceENTER_uxStreamBufferGetStreamBufferNotificationIndex( xStreamBuffer ) +#endif + +#ifndef traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex + #define traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex( uxNotificationIndex ) +#endif + +#ifndef traceENTER_vStreamBufferSetStreamBufferNotificationIndex + #define traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex ) +#endif + +#ifndef traceRETURN_vStreamBufferSetStreamBufferNotificationIndex + #define traceRETURN_vStreamBufferSetStreamBufferNotificationIndex() +#endif + #ifndef traceENTER_uxStreamBufferGetStreamBufferNumber #define traceENTER_uxStreamBufferGetStreamBufferNumber( xStreamBuffer ) #endif @@ -2603,10 +2704,6 @@ #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() #endif -#ifndef configUSE_MALLOC_FAILED_HOOK - #define configUSE_MALLOC_FAILED_HOOK 0 -#endif - #ifndef portPRIVILEGE_BIT #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) #endif @@ -2759,9 +2856,9 @@ #ifndef configSTACK_DEPTH_TYPE -/* Defaults to uint16_t for backward compatibility, but can be overridden - * in FreeRTOSConfig.h if uint16_t is too restrictive. */ - #define configSTACK_DEPTH_TYPE uint16_t +/* Defaults to StackType_t for backward compatibility, but can be overridden + * in FreeRTOSConfig.h if StackType_t is too restrictive. */ + #define configSTACK_DEPTH_TYPE StackType_t #endif #ifndef configRUN_TIME_COUNTER_TYPE @@ -3247,6 +3344,7 @@ typedef struct xSTATIC_STREAM_BUFFER #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) void * pvDummy5[ 2 ]; #endif + UBaseType_t uxDummy6; } StaticStreamBuffer_t; /* Message buffers are built on stream buffers. */ diff --git a/include/StackMacros.h b/include/StackMacros.h index b8ed92e31..d0c624733 100644 --- a/include/StackMacros.h +++ b/include/StackMacros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/include/atomic.h b/include/atomic.h index 8feb65250..335a77fdf 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -33,6 +33,14 @@ * This file implements atomic functions by disabling interrupts globally. * Implementations with architecture specific atomic instructions can be * provided under each compiler directory. + * + * The atomic interface can be used in FreeRTOS tasks on all FreeRTOS ports. It + * can also be used in Interrupt Service Routines (ISRs) on FreeRTOS ports that + * support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1). The + * atomic interface must not be used in ISRs on FreeRTOS ports that do not + * support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0) + * because ISRs on these ports cannot be interrupted and therefore, do not need + * atomics in ISRs. */ #ifndef ATOMIC_H @@ -59,7 +67,7 @@ * ATOMIC_ENTER_CRITICAL(). * */ -#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) +#if ( portHAS_NESTED_INTERRUPTS == 1 ) /* Nested interrupt scheme is supported in this port. */ #define ATOMIC_ENTER_CRITICAL() \ diff --git a/include/croutine.h b/include/croutine.h index 40ac9765b..a5e2e4462 100644 --- a/include/croutine.h +++ b/include/croutine.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -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 @@ -746,6 +749,13 @@ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, */ BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ); + +/* + * This function resets the internal state of the coroutine module. It must be + * called by the application before restarting the scheduler. + */ +void vCoRoutineResetState( void ) PRIVILEGED_FUNCTION; + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/include/deprecated_definitions.h b/include/deprecated_definitions.h index b046711a6..edc0f2246 100644 --- a/include/deprecated_definitions.h +++ b/include/deprecated_definitions.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/include/event_groups.h b/include/event_groups.h index d66ab262c..d42c87b28 100644 --- a/include/event_groups.h +++ b/include/event_groups.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -45,15 +45,15 @@ #define eventWAIT_FOR_ALL_BITS ( ( uint16_t ) 0x0400U ) #define eventEVENT_BITS_CONTROL_BYTES ( ( uint16_t ) 0xff00U ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - #define eventCLEAR_EVENTS_ON_EXIT_BIT ( ( uint32_t ) 0x01000000UL ) - #define eventUNBLOCKED_DUE_TO_BIT_SET ( ( uint32_t ) 0x02000000UL ) - #define eventWAIT_FOR_ALL_BITS ( ( uint32_t ) 0x04000000UL ) - #define eventEVENT_BITS_CONTROL_BYTES ( ( uint32_t ) 0xff000000UL ) + #define eventCLEAR_EVENTS_ON_EXIT_BIT ( ( uint32_t ) 0x01000000U ) + #define eventUNBLOCKED_DUE_TO_BIT_SET ( ( uint32_t ) 0x02000000U ) + #define eventWAIT_FOR_ALL_BITS ( ( uint32_t ) 0x04000000U ) + #define eventEVENT_BITS_CONTROL_BYTES ( ( uint32_t ) 0xff000000U ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) - #define eventCLEAR_EVENTS_ON_EXIT_BIT ( ( uint64_t ) 0x0100000000000000ULL ) - #define eventUNBLOCKED_DUE_TO_BIT_SET ( ( uint64_t ) 0x0200000000000000ULL ) - #define eventWAIT_FOR_ALL_BITS ( ( uint64_t ) 0x0400000000000000ULL ) - #define eventEVENT_BITS_CONTROL_BYTES ( ( uint64_t ) 0xff00000000000000ULL ) + #define eventCLEAR_EVENTS_ON_EXIT_BIT ( ( uint64_t ) 0x0100000000000000U ) + #define eventUNBLOCKED_DUE_TO_BIT_SET ( ( uint64_t ) 0x0200000000000000U ) + #define eventWAIT_FOR_ALL_BITS ( ( uint64_t ) 0x0400000000000000U ) + #define eventEVENT_BITS_CONTROL_BYTES ( ( uint64_t ) 0xff00000000000000U ) #endif /* if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) */ /* *INDENT-OFF* */ @@ -139,6 +139,9 @@ typedef TickType_t EventBits_t; * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type * is used to store event bits within an event group. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupCreate() + * to be available. + * * @return If the event group was created then a handle to the event group is * returned. If there was insufficient FreeRTOS heap available to create the * event group then NULL is returned. See https://www.FreeRTOS.org/a00111.html @@ -196,6 +199,9 @@ typedef TickType_t EventBits_t; * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type * is used to store event bits within an event group. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupCreateStatic() + * to be available. + * * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type * StaticEventGroup_t, which will be then be used to hold the event group's data * structures, removing the need for the memory to be allocated dynamically. @@ -238,6 +244,9 @@ typedef TickType_t EventBits_t; * * This function cannot be called from an interrupt. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupWaitBits() + * to be available. + * * @param xEventGroup The event group in which the bits are being tested. The * event group must have previously been created using a call to * xEventGroupCreate(). @@ -331,6 +340,9 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, * Clear bits within an event group. This function cannot be called from an * interrupt. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupClearBits() + * to be available. + * * @param xEventGroup The event group in which the bits are to be cleared. * * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear @@ -440,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 @@ -461,6 +470,9 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * Setting bits in an event group will automatically unblock tasks that are * blocked waiting for the bits. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupSetBits() + * to be available. + * * @param xEventGroup The event group in which the bits are to be set. * * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. @@ -468,14 +480,11 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * and bit 0 set uxBitsToSet to 0x09. * * @return The value of the event group at the time the call to - * xEventGroupSetBits() returns. There are two reasons why the returned value - * might have the bits specified by the uxBitsToSet parameter cleared. First, - * if setting a bit results in a task that was waiting for the bit leaving the - * blocked state then it is possible the bit will be cleared automatically - * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any - * unblocked (or otherwise Ready state) task that has a priority above that of - * the task that called xEventGroupSetBits() will execute and may change the - * event group value before the call to xEventGroupSetBits() returns. + * xEventGroupSetBits() returns. Returned value might have the bits specified + * by the uxBitsToSet parameter cleared if setting a bit results in a task + * that was waiting for the bit leaving the blocked state then it is possible + * the bit will be cleared automatically (see the xClearBitOnExit parameter + * of xEventGroupWaitBits()). * * Example usage: * @code{c} @@ -595,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 @@ -625,6 +631,9 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * this case all the bits specified by uxBitsToWait will be automatically * cleared before the function returns. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupSync() + * to be available. + * * @param xEventGroup The event group in which the bits are being tested. The * event group must have previously been created using a call to * xEventGroupCreate(). @@ -743,6 +752,9 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * Returns the current value of the bits in an event group. This function * cannot be used from an interrupt. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetBits() + * to be available. + * * @param xEventGroup The event group being queried. * * @return The event group bits at the time xEventGroupGetBits() was called. @@ -760,6 +772,9 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * * A version of xEventGroupGetBits() that can be called from an ISR. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetBitsFromISR() + * to be available. + * * @param xEventGroup The event group being queried. * * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. @@ -779,6 +794,9 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG * xEventGroupCreate(). Tasks that are blocked on the event group will be * unblocked and obtain 0 as the event group's value. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for vEventGroupDelete() + * to be available. + * * @param xEventGroup The event group being deleted. */ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; @@ -793,6 +811,9 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; * Retrieve a pointer to a statically created event groups's data structure * buffer. It is the same buffer that is supplied at the time of creation. * + * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetStaticBuffer() + * to be available. + * * @param xEventGroup The event group for which to retrieve the buffer. * * @param ppxEventGroupBuffer Used to return a pointer to the event groups's diff --git a/include/list.h b/include/list.h index 7084834dc..b6e0d34f4 100644 --- a/include/list.h +++ b/include/list.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -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. @@ -172,7 +172,7 @@ typedef struct xLIST_ITEM ListItem_t; typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ - volatile UBaseType_t uxNumberOfItems; + configLIST_VOLATILE UBaseType_t uxNumberOfItems; ListItem_t * configLIST_VOLATILE pxIndex; /**< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ MiniListItem_t xListEnd; /**< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ listSECOND_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ @@ -282,7 +282,8 @@ typedef struct xLIST * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY * \ingroup LinkedList */ -#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +#if ( configNUMBER_OF_CORES == 1 ) + #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ do { \ List_t * const pxConstList = ( pxList ); \ /* Increment the index to the next item and return the item, ensuring */ \ @@ -294,6 +295,13 @@ typedef struct xLIST } \ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ } while( 0 ) +#else /* #if ( configNUMBER_OF_CORES == 1 ) */ + +/* This function is not required in SMP. FreeRTOS SMP scheduler doesn't use + * pxIndex and it should always point to the xListEnd. Not defining this macro + * here to prevent updating pxIndex. + */ +#endif /* #if ( configNUMBER_OF_CORES == 1 ) */ /* * Version of uxListRemove() that does not return a value. Provided as a slight @@ -314,19 +322,19 @@ typedef struct xLIST #define listREMOVE_ITEM( pxItemToRemove ) \ do { \ /* The list item knows which list it is in. Obtain the list from the list \ - * item. */ \ - List_t * const pxList = ( pxItemToRemove )->pxContainer; \ - \ - ( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \ - ( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \ - /* Make sure the index is left pointing to a valid item. */ \ - if( pxList->pxIndex == ( pxItemToRemove ) ) \ - { \ - pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \ - } \ - \ - ( pxItemToRemove )->pxContainer = NULL; \ - ( pxList->uxNumberOfItems )--; \ + * item. */ \ + List_t * const pxList = ( pxItemToRemove )->pxContainer; \ + \ + ( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \ + ( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \ + /* Make sure the index is left pointing to a valid item. */ \ + if( pxList->pxIndex == ( pxItemToRemove ) ) \ + { \ + pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \ + } \ + \ + ( pxItemToRemove )->pxContainer = NULL; \ + ( ( pxList )->uxNumberOfItems ) = ( UBaseType_t ) ( ( ( pxList )->uxNumberOfItems ) - 1U ); \ } while( 0 ) /* @@ -363,17 +371,17 @@ typedef struct xLIST \ /* Insert a new list item into ( pxList ), but rather than sort the list, \ * makes the new list item the last item to be removed by a call to \ - * listGET_OWNER_OF_NEXT_ENTRY(). */ \ - ( pxNewListItem )->pxNext = pxIndex; \ - ( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \ - \ - pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \ - pxIndex->pxPrevious = ( pxNewListItem ); \ - \ - /* Remember which list the item is in. */ \ - ( pxNewListItem )->pxContainer = ( pxList ); \ - \ - ( ( pxList )->uxNumberOfItems )++; \ + * listGET_OWNER_OF_NEXT_ENTRY(). */ \ + ( pxNewListItem )->pxNext = pxIndex; \ + ( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \ + \ + pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \ + pxIndex->pxPrevious = ( pxNewListItem ); \ + \ + /* Remember which list the item is in. */ \ + ( pxNewListItem )->pxContainer = ( pxList ); \ + \ + ( ( pxList )->uxNumberOfItems ) = ( UBaseType_t ) ( ( ( pxList )->uxNumberOfItems ) + 1U ); \ } while( 0 ) /* diff --git a/include/message_buffer.h b/include/message_buffer.h index 74fab118f..9fb97ffd0 100644 --- a/include/message_buffer.h +++ b/include/message_buffer.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -43,12 +43,12 @@ * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xMessageBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xMessageBufferRead()) inside a critical section and set the receive - * timeout to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Message buffers hold variable length messages. To enable that, when a * message is written to the message buffer an additional sizeof( size_t ) bytes @@ -100,6 +100,8 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in * FreeRTOSConfig.h for xMessageBufferCreate() to be available. + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferCreate() to be available. * * @param xBufferSizeBytes The total number of bytes (not messages) the message * buffer will be able to hold at any one time. When a message is written to @@ -156,11 +158,11 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * \ingroup MessageBufferManagement */ #define xMessageBufferCreate( xBufferSizeBytes ) \ - xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, NULL, NULL ) + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** @@ -168,12 +170,15 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * @code{c} * MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes, - * uint8_t *pucMessageBufferStorageArea, - * StaticMessageBuffer_t *pxStaticMessageBuffer ); + * uint8_t *pucMessageBufferStorageArea, + * StaticMessageBuffer_t *pxStaticMessageBuffer ); * @endcode * Creates a new message buffer using statically allocated memory. See * xMessageBufferCreate() for a version that uses dynamically allocated memory. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferCreateStatic() to be available. + * * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the * pucMessageBufferStorageArea parameter. When a message is written to the * message buffer an additional sizeof( size_t ) bytes are also written to store @@ -238,11 +243,11 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * \ingroup MessageBufferManagement */ #define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, sbTYPE_MESSAGE_BUFFER, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, sbTYPE_MESSAGE_BUFFER, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** @@ -258,6 +263,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * buffer and storage area buffer. These are the same buffers that are supplied * at the time of creation. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferGetStaticBuffers() to be available. + * * @param xMessageBuffer The message buffer for which to retrieve the buffers. * * @param ppucMessageBufferStorageArea Used to return a pointer to the @@ -281,9 +289,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * @code{c} * size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer, - * const void *pvTxData, - * size_t xDataLengthBytes, - * TickType_t xTicksToWait ); + * const void *pvTxData, + * size_t xDataLengthBytes, + * TickType_t xTicksToWait ); * @endcode * * Sends a discrete message to the message buffer. The message can be any @@ -298,17 +306,20 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xMessageBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xMessageBufferRead()) inside a critical section and set the receive - * block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Use xMessageBufferSend() to write to a message buffer from a task. Use * xMessageBufferSendFromISR() to write to a message buffer from an interrupt * service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferSend() to be available. + * * @param xMessageBuffer The handle of the message buffer to which a message is * being sent. * @@ -381,9 +392,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * @code{c} * size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer, - * const void *pvTxData, - * size_t xDataLengthBytes, - * BaseType_t *pxHigherPriorityTaskWoken ); + * const void *pvTxData, + * size_t xDataLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * Interrupt safe version of the API function that sends a discrete message to @@ -398,17 +409,20 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xMessageBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xMessageBufferRead()) inside a critical section and set the receive - * block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Use xMessageBufferSend() to write to a message buffer from a task. Use * xMessageBufferSendFromISR() to write to a message buffer from an interrupt * service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferSendFromISR() to be available. + * * @param xMessageBuffer The handle of the message buffer to which a message is * being sent. * @@ -486,9 +500,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * @code{c} * size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer, - * void *pvRxData, - * size_t xBufferLengthBytes, - * TickType_t xTicksToWait ); + * void *pvRxData, + * size_t xBufferLengthBytes, + * TickType_t xTicksToWait ); * @endcode * * Receives a discrete message from a message buffer. Messages can be of @@ -502,17 +516,20 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xMessageBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xMessageBufferRead()) inside a critical section and set the receive - * block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Use xMessageBufferReceive() to read from a message buffer from a task. Use * xMessageBufferReceiveFromISR() to read from a message buffer from an * interrupt service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferReceive() to be available. + * * @param xMessageBuffer The handle of the message buffer from which a message * is being received. * @@ -576,9 +593,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * @code{c} * size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer, - * void *pvRxData, - * size_t xBufferLengthBytes, - * BaseType_t *pxHigherPriorityTaskWoken ); + * void *pvRxData, + * size_t xBufferLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * An interrupt safe version of the API function that receives a discrete @@ -593,17 +610,20 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xMessageBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xMessageBufferRead()) inside a critical section and set the receive - * block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Use xMessageBufferReceive() to read from a message buffer from a task. Use * xMessageBufferReceiveFromISR() to read from a message buffer from an * interrupt service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferReceiveFromISR() to be available. + * * @param xMessageBuffer The handle of the message buffer from which a message * is being received. * @@ -687,6 +707,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * A message buffer handle must not be used after the message buffer has been * deleted. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * vMessageBufferDelete() to be available. + * * @param xMessageBuffer The handle of the message buffer to be deleted. * */ @@ -703,6 +726,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * cannot accept any more messages, of any size, until space is made available * by a message being removed from the message buffer. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferIsFull() to be available. + * * @param xMessageBuffer The handle of the message buffer being queried. * * @return If the message buffer referenced by xMessageBuffer is full then @@ -719,6 +745,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * Tests to see if a message buffer is empty (does not contain any messages). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferIsEmpty() to be available. + * * @param xMessageBuffer The handle of the message buffer being queried. * * @return If the message buffer referenced by xMessageBuffer is empty then @@ -739,6 +768,13 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * A message buffer can only be reset if there are no tasks blocked on it. * + * Use xMessageBufferReset() to reset a message buffer from a task. + * Use xMessageBufferResetFromISR() to reset a message buffer from an + * interrupt service routine (ISR). + * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferReset() to be available. + * * @param xMessageBuffer The handle of the message buffer being reset. * * @return If the message buffer was reset then pdPASS is returned. If the @@ -753,6 +789,38 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; xStreamBufferReset( xMessageBuffer ) +/** + * message_buffer.h + * @code{c} + * BaseType_t xMessageBufferResetFromISR( MessageBufferHandle_t xMessageBuffer ); + * @endcode + * + * An interrupt safe version of the API function that resets the message buffer. + * Resets a message buffer to its initial empty state, discarding any message it + * contained. + * + * A message buffer can only be reset if there are no tasks blocked on it. + * + * Use xMessageBufferReset() to reset a message buffer from a task. + * Use xMessageBufferResetFromISR() to reset a message buffer from an + * interrupt service routine (ISR). + * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferResetFromISR() to be available. + * + * @param xMessageBuffer The handle of the message buffer being reset. + * + * @return If the message buffer was reset then pdPASS is returned. If the + * message buffer could not be reset because either there was a task blocked on + * the message queue to wait for space to become available, or to wait for a + * a message to be available, then pdFAIL is returned. + * + * \defgroup xMessageBufferResetFromISR xMessageBufferResetFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferResetFromISR( xMessageBuffer ) \ + xStreamBufferResetFromISR( xMessageBuffer ) + /** * message_buffer.h * @code{c} @@ -760,6 +828,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * @endcode * Returns the number of bytes of free space in the message buffer. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferSpaceAvailable() to be available. + * * @param xMessageBuffer The handle of the message buffer being queried. * * @return The number of bytes that can be written to the message buffer before @@ -786,6 +857,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * Useful if xMessageBufferReceive() returned 0 because the size of the buffer * passed into xMessageBufferReceive() was too small to hold the next message. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferNextLengthBytes() to be available. + * * @param xMessageBuffer The handle of the message buffer being queried. * * @return The length (in bytes) of the next message in the message buffer, or 0 @@ -795,7 +869,7 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * \ingroup MessageBufferManagement */ #define xMessageBufferNextLengthBytes( xMessageBuffer ) \ - xStreamBufferNextMessageLengthBytes( xMessageBuffer ) PRIVILEGED_FUNCTION; + xStreamBufferNextMessageLengthBytes( xMessageBuffer ) /** * message_buffer.h @@ -817,6 +891,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferSendCompletedFromISR() to be available. + * * @param xMessageBuffer The handle of the stream buffer to which data was * written. * @@ -858,6 +935,9 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xMessageBufferReceiveCompletedFromISR() to be available. + * * @param xMessageBuffer The handle of the stream buffer from which data was * read. * diff --git a/include/mpu_prototypes.h b/include/mpu_prototypes.h index 547320180..b4c0f4745 100644 --- a/include/mpu_prototypes.h +++ b/include/mpu_prototypes.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -136,25 +136,59 @@ BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; /* Privileged only wrappers for Task APIs. These are needed so that * the application can use opaque handles maintained in mpu_wrappers.c * with all the APIs. */ -BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, - const char * const pcName, - const uint16_t usStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; -TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, - const char * const pcName, - const uint32_t ulStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - StackType_t * const puxStackBuffer, - StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; -void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; -void MPU_vTaskPrioritySet( TaskHandle_t xTask, - UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; -TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; -BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, - void * pvParameter ) PRIVILEGED_FUNCTION; +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE uxStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE uxStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskPrioritySet( TaskHandle_t xTask, + UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; + TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskGetRunTimeStatistics( char * pcWriteBuffer, + size_t uxBufferLength ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskListTasks( char * pcWriteBuffer, + size_t uxBufferLength ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE uxStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE uxStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; + void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + void MPU_vTaskPrioritySet( TaskHandle_t xTask, + UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; @@ -215,28 +249,64 @@ uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; /* Privileged only wrappers for Queue APIs. These are needed so that * the application can use opaque handles maintained in mpu_wrappers.c * with all the APIs. */ -void MPU_vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; -QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; -QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, - StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; -QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, - const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; -QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, - const UBaseType_t uxInitialCount, - StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; -QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, - const UBaseType_t uxItemSize, - const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; -QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, - const UBaseType_t uxItemSize, - uint8_t * pucQueueStorage, - StaticQueue_t * pxStaticQueue, - const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; -QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; -BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, - QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; -BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, - BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; + QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; + QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + void MPU_vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; + QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, uint8_t ** ppucQueueStorage, StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION; @@ -271,7 +341,7 @@ BaseType_t MPU_xTimerGenericCommandFromTask( TimerHandle_t xTimer, BaseType_t MPU_xTimerGenericCommandFromTaskEntry( const xTimerGenericCommandFromTaskParams_t * pxParams ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; @@ -282,12 +352,12 @@ TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; * with all the APIs. */ TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION; @@ -318,23 +388,37 @@ EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL; -#endif /* ( configUSE_TRACE_FACILITY == 1 )*/ +#endif /* #if ( configUSE_TRACE_FACILITY == 1 ) */ /* Privileged only wrappers for Event Group APIs. These are needed so that * the application can use opaque handles maintained in mpu_wrappers.c * with all the APIs. */ -EventGroupHandle_t MPU_xEventGroupCreate( void ) PRIVILEGED_FUNCTION; -EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; -void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + EventGroupHandle_t MPU_xEventGroupCreate( void ) PRIVILEGED_FUNCTION; + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + 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, @@ -355,20 +439,42 @@ size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuff /* Privileged only wrappers for Stream Buffer APIs. These are needed so that * the application can use opaque handles maintained in mpu_wrappers.c * with all the APIs. */ -StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, - size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, - StreamBufferCallbackFunction_t pxSendCompletedCallback, - StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; -StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, - size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, - uint8_t * const pucStreamBufferStorageArea, - StaticStreamBuffer_t * const pxStaticStreamBuffer, - StreamBufferCallbackFunction_t pxSendCompletedCallback, - StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; -void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; -BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers, uint8_t * ppucStreamBufferStorageArea, StaticStreamBuffer_t * ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION; @@ -384,5 +490,6 @@ BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBu BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; #endif /* MPU_PROTOTYPES_H */ diff --git a/include/mpu_syscall_numbers.h b/include/mpu_syscall_numbers.h index 47913c998..7c625a78d 100644 --- a/include/mpu_syscall_numbers.h +++ b/include/mpu_syscall_numbers.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/include/mpu_wrappers.h b/include/mpu_wrappers.h index 51e7bcf40..3b4738e96 100644 --- a/include/mpu_wrappers.h +++ b/include/mpu_wrappers.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -85,6 +85,18 @@ /* Privileged only wrappers for Task APIs. These are needed so that * the application can use opaque handles maintained in mpu_wrappers.c * with all the APIs. */ + #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + +/* These are not needed in v2 because they do not take a task + * handle and therefore, no lookup is needed. Needed in v1 because + * these are available as system calls in v1. */ + #define vTaskGetRunTimeStatistics MPU_vTaskGetRunTimeStatistics + #define vTaskListTasks MPU_vTaskListTasks + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskCatchUpTicks MPU_xTaskCatchUpTicks + #define xTaskResumeAll MPU_xTaskResumeAll + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + #define xTaskCreate MPU_xTaskCreate #define xTaskCreateStatic MPU_xTaskCreateStatic #define vTaskDelete MPU_vTaskDelete @@ -138,6 +150,7 @@ #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic #define xQueueGenericReset MPU_xQueueGenericReset #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueCreateSetStatic MPU_xQueueCreateSetStatic #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) @@ -165,11 +178,14 @@ #define xTimerGetPeriod MPU_xTimerGetPeriod #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xTimerGetReloadMode MPU_xTimerGetReloadMode + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + /* Privileged only wrappers for Timer APIs. These are needed so that * the application can use opaque handles maintained in mpu_wrappers.c * with all the APIs. */ #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) - #define xTimerGetReloadMode MPU_xTimerGetReloadMode #define xTimerCreate MPU_xTimerCreate #define xTimerCreateStatic MPU_xTimerCreateStatic #define xTimerGetStaticBuffer MPU_xTimerGetStaticBuffer @@ -227,16 +243,9 @@ #define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR #define xStreamBufferSendCompletedFromISR MPU_xStreamBufferSendCompletedFromISR #define xStreamBufferReceiveCompletedFromISR MPU_xStreamBufferReceiveCompletedFromISR + #define xStreamBufferResetFromISR MPU_xStreamBufferResetFromISR #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ -/* Remove the privileged function macro, but keep the PRIVILEGED_DATA - * macro so applications can place data in privileged access sections - * (useful when using statically allocated objects). */ - #define PRIVILEGED_FUNCTION - #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) - #define FREERTOS_SYSTEM_CALL - - #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) #define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) ) @@ -265,15 +274,12 @@ #endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ - #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ - -/* Ensure API functions go in the privileged execution section. */ - #define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) ) - #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) - #define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) ) - #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + #define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) ) + #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) + #define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) ) + #else /* portUSING_MPU_WRAPPERS */ #define PRIVILEGED_FUNCTION diff --git a/include/newlib-freertos.h b/include/newlib-freertos.h index a65e62e8e..4414d24ad 100644 --- a/include/newlib-freertos.h +++ b/include/newlib-freertos.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/include/picolibc-freertos.h b/include/picolibc-freertos.h index ef6b7570c..5cf01afa8 100644 --- a/include/picolibc-freertos.h +++ b/include/picolibc-freertos.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/include/portable.h b/include/portable.h index ab8a26df0..68e11e793 100644 --- a/include/portable.h +++ b/include/portable.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -85,19 +85,31 @@ #define portARCH_NAME NULL #endif +#ifndef portBASE_TYPE_ENTER_CRITICAL + #define portBASE_TYPE_ENTER_CRITICAL() taskENTER_CRITICAL() +#endif + +#ifndef portBASE_TYPE_EXIT_CRITICAL + #define portBASE_TYPE_EXIT_CRITICAL() taskEXIT_CRITICAL() +#endif + +#ifndef configSTACK_DEPTH_TYPE + #define configSTACK_DEPTH_TYPE StackType_t +#endif + #ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP /* Defaults to 0 for backward compatibility. */ #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 #endif +#include "mpu_wrappers.h" + /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ -#include "mpu_wrappers.h" - /* * Setup the stack of a new task so it is ready to be placed under the * scheduler control. The registers have to be placed on the stack in @@ -174,13 +186,14 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats ); /* * Map to the memory management routines required for the port. */ -void * pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void * pvPortMalloc( size_t xWantedSize ) PRIVILEGED_FUNCTION; void * pvPortCalloc( size_t xNum, size_t xSize ) PRIVILEGED_FUNCTION; void vPortFree( void * pv ) PRIVILEGED_FUNCTION; void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; +void xPortResetHeapMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; #if ( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 ) void * pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION; @@ -190,6 +203,12 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; #define vPortFreeStack vPortFree #endif +/* + * This function resets the internal state of the heap module. It must be called + * by the application before restarting the scheduler. + */ +void vPortHeapResetState( void ) PRIVILEGED_FUNCTION; + #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) /** @@ -228,7 +247,7 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; + configSTACK_DEPTH_TYPE uxStackDepth ) PRIVILEGED_FUNCTION; #endif /** diff --git a/include/projdefs.h b/include/projdefs.h index 370285d30..04ec47fae 100644 --- a/include/projdefs.h +++ b/include/projdefs.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/include/queue.h b/include/queue.h index c6497b5b6..56753d300 100644 --- a/include/queue.h +++ b/include/queue.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -34,14 +34,14 @@ #error "include FreeRTOS.h" must appear in source files before "include queue.h" #endif +#include "task.h" + /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ -#include "task.h" - /** * Type by which queues are referenced. For example, a call to xQueueCreate() * returns an QueueHandle_t variable that can then be used as a parameter to @@ -71,11 +71,11 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /* For internal use only. These definitions *must* match those in queue.c. */ #define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) -#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) #define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) #define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) #define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) #define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 5U ) /** * queue. h @@ -109,7 +109,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * the same size. * * @return If the queue is successfully create then a handle to the newly - * created queue is returned. If the queue cannot be created then 0 is + * created queue is returned. If the queue cannot be created then NULL is * returned. * * Example usage: @@ -126,7 +126,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * * // Create a queue capable of containing 10 uint32_t values. * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); - * if( xQueue1 == 0 ) + * if( xQueue1 == NULL ) * { * // Queue was not created and must not be used. * } @@ -134,7 +134,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * // Create a queue capable of containing 10 pointers to AMessage structures. * // These should be passed by pointer as they contain a lot of data. * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); - * if( xQueue2 == 0 ) + * if( xQueue2 == NULL ) * { * // Queue was not created and must not be used. * } @@ -292,7 +292,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * queue is full. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * @return pdPASS if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} @@ -302,7 +302,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * char ucData[ 20 ]; * } xMessage; * - * uint32_t ulVar = 10UL; + * uint32_t ulVar = 10U; * * void vATask( void *pvParameters ) * { @@ -375,7 +375,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * is full. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * @return pdPASS if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} @@ -385,7 +385,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * char ucData[ 20 ]; * } xMessage; * - * uint32_t ulVar = 10UL; + * uint32_t ulVar = 10U; * * void vATask( void *pvParameters ) * { @@ -460,7 +460,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * queue is full. The time is defined in tick periods so the constant * portTICK_PERIOD_MS should be used to convert to real time if this is required. * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * @return pdPASS if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} @@ -470,7 +470,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * char ucData[ 20 ]; * } xMessage; * - * uint32_t ulVar = 10UL; + * uint32_t ulVar = 10U; * * void vATask( void *pvParameters ) * { @@ -633,7 +633,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * item at the back of the queue, or queueSEND_TO_FRONT to place the item * at the front of the queue (for high priority messages). * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * @return pdPASS if the item was successfully posted, otherwise errQUEUE_FULL. * * Example usage: * @code{c} @@ -643,7 +643,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * char ucData[ 20 ]; * } xMessage; * - * uint32_t ulVar = 10UL; + * uint32_t ulVar = 10U; * * void vATask( void *pvParameters ) * { @@ -723,8 +723,8 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue * is empty. * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. + * @return pdPASS if an item was successfully received from the queue, + * otherwise errQUEUE_EMPTY. * * Example usage: * @code{c} @@ -811,8 +811,8 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, * @param pvBuffer Pointer to the buffer into which the received item will * be copied. * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. + * @return pdPASS if an item was successfully received from the queue, + * otherwise pdFAIL. * * \defgroup xQueuePeekFromISR xQueuePeekFromISR * \ingroup QueueManagement @@ -852,8 +852,8 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, * constant portTICK_PERIOD_MS should be used to convert to real time if this is * required. * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. + * @return pdPASS if an item was successfully received from the queue, + * otherwise errQUEUE_EMPTY. * * Example usage: * @code{c} @@ -998,7 +998,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * running task. If xQueueSendToFrontFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * - * @return pdTRUE if the data was successfully sent to the queue, otherwise + * @return pdPASS if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value @@ -1070,7 +1070,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * - * @return pdTRUE if the data was successfully sent to the queue, otherwise + * @return pdPASS if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value @@ -1235,7 +1235,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * running task. If xQueueSendFromISR() sets this value to pdTRUE then * a context switch should be requested before the interrupt is exited. * - * @return pdTRUE if the data was successfully sent to the queue, otherwise + * @return pdPASS if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value @@ -1318,7 +1318,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * item at the back of the queue, or queueSEND_TO_FRONT to place the item * at the front of the queue (for high priority messages). * - * @return pdTRUE if the data was successfully sent to the queue, otherwise + * @return pdPASS if the data was successfully sent to the queue, otherwise * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value @@ -1389,8 +1389,8 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * to unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will * remain unchanged. * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. + * @return pdPASS if an item was successfully received from the queue, + * otherwise pdFAIL. * * Example usage: * @code{c} @@ -1522,8 +1522,8 @@ BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, #endif /* - * For internal use only. Use xSemaphoreTakeMutexRecursive() or - * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + * For internal use only. Use xSemaphoreTakeRecursive() or + * xSemaphoreGiveRecursive() instead of calling these functions directly. */ BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; @@ -1638,14 +1638,14 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. * - * A queue set must be explicitly created using a call to xQueueCreateSet() - * before it can be used. Once created, standard FreeRTOS queues and semaphores - * can be added to the set using calls to xQueueAddToSet(). - * xQueueSelectFromSet() is then used to determine which, if any, of the queues - * or semaphores contained in the set is in a state where a queue read or - * semaphore take operation would be successful. + * A queue set must be explicitly created using a call to xQueueCreateSet() or + * xQueueCreateSetStatic() before it can be used. Once created, standard + * FreeRTOS queues and semaphores can be added to the set using calls to + * xQueueAddToSet(). xQueueSelectFromSet() is then used to determine which, if + * any, of the queues or semaphores contained in the set is in a state where a + * queue read or semaphore take operation would be successful. * - * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html + * Note 1: See the documentation on https://www.freertos.org/Documentation/02-Kernel/04-API-references/07-Queue-sets/00-RTOS-queue-sets * for reasons why queue sets are very rarely needed in practice as there are * simpler methods of blocking on multiple objects. * @@ -1683,9 +1683,69 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; #endif +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * or xQueueCreateSetStatic() before it can be used. Once created, standard + * FreeRTOS queues and semaphores can be added to the set using calls to + * xQueueAddToSet(). xQueueSelectFromSet() is then used to determine which, if + * any, of the queues or semaphores contained in the set is in a state where a + * queue read or semaphore take operation would be successful. + * + * Note 1: See the documentation on https://www.freertos.org/Documentation/02-Kernel/04-API-references/07-Queue-sets/00-RTOS-queue-sets + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @param pucQueueStorage pucQueueStorage must point to a uint8_t array that is + * at least large enough to hold uxEventQueueLength events. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. If pxQueueBuffer is NULL then NULL is returned. + */ +#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + QueueSetHandle_t xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; +#endif + /* * Adds a queue or semaphore to a queue set that was previously created by a - * call to xQueueCreateSet(). + * call to xQueueCreateSet() or xQueueCreateSetStatic(). * * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. @@ -1742,7 +1802,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this * function. * - * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html + * Note 1: See the documentation on https://www.freertos.org/Documentation/02-Kernel/04-API-references/07-Queue-sets/00-RTOS-queue-sets * for reasons why queue sets are very rarely needed in practice as there are * simpler methods of blocking on multiple objects. * diff --git a/include/semphr.h b/include/semphr.h index e93b708c5..7b44d78c0 100644 --- a/include/semphr.h +++ b/include/semphr.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -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/include/stack_macros.h b/include/stack_macros.h index bd9ec2770..6d0117722 100644 --- a/include/stack_macros.h +++ b/include/stack_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -53,11 +53,23 @@ #define portSTACK_LIMIT_PADDING 0 #endif -#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) +/* Stack overflow check is not straight forward to implement for MPU ports + * because of the following reasons: + * 1. The context is stored in TCB and as a result, pxTopOfStack member points + * to the context location in TCB. + * 2. System calls are executed on a separate privileged only stack. + * + * It is still okay because an MPU region is used to protect task stack which + * means task stack overflow will trigger an MPU fault for unprivileged tasks. + * Additionally, architectures with hardware stack overflow checking support + * (such as Armv8-M) will trigger a fault when a task's stack overflows. + */ +#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) ) /* Only the current stack state is to be checked. */ #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ + do \ + { \ /* Is the currently saved stack pointer within the stack limit? */ \ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \ { \ @@ -69,12 +81,12 @@ #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ /*-----------------------------------------------------------*/ -#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) +#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) ) /* Only the current stack state is to be checked. */ #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ - \ + do \ + { \ /* Is the currently saved stack pointer within the stack limit? */ \ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ { \ @@ -86,30 +98,33 @@ #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ /*-----------------------------------------------------------*/ -#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) +#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) ) - #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ - const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ - const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \ - \ - if( ( pulStack[ 0 ] != ulCheckValue ) || \ - ( pulStack[ 1 ] != ulCheckValue ) || \ - ( pulStack[ 2 ] != ulCheckValue ) || \ - ( pulStack[ 3 ] != ulCheckValue ) ) \ - { \ - char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ - vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ - } \ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + do \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \ + \ + if( ( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \ + ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ + } \ } while( 0 ) #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ /*-----------------------------------------------------------*/ -#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) +#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) && ( portUSING_MPU_WRAPPERS != 1 ) ) #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ + do \ + { \ int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ @@ -117,11 +132,10 @@ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ \ - \ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ \ - /* Has the extremity of the task stack ever been written over? */ \ - if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + if( ( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \ + ( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) ) \ { \ char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ diff --git a/include/stdint.readme b/include/stdint.readme index 5c9d192ec..bfe3bb6f8 100644 --- a/include/stdint.readme +++ b/include/stdint.readme @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/include/stream_buffer.h b/include/stream_buffer.h index 68d12e08f..b0093fc80 100644 --- a/include/stream_buffer.h +++ b/include/stream_buffer.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -40,12 +40,12 @@ * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xStreamBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xStreamBufferReceive()) inside a critical section section and set the - * receive block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * */ @@ -62,6 +62,13 @@ #endif /* *INDENT-ON* */ +/** + * Type of stream buffer. For internal use only. + */ +#define sbTYPE_STREAM_BUFFER ( ( BaseType_t ) 0 ) +#define sbTYPE_MESSAGE_BUFFER ( ( BaseType_t ) 1 ) +#define sbTYPE_STREAM_BATCHING_BUFFER ( ( BaseType_t ) 2 ) + /** * Type by which stream buffers are referenced. For example, a call to * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can @@ -91,6 +98,8 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf * * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in * FreeRTOSConfig.h for xStreamBufferCreate() to be available. + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferCreate() to be available. * * @param xBufferSizeBytes The total number of bytes the stream buffer will be * able to hold at any one time. @@ -155,11 +164,11 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf */ #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \ - xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, NULL, NULL ) + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BUFFER, NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xStreamBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BUFFER, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** @@ -167,15 +176,17 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf * * @code{c} * StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes, - * size_t xTriggerLevelBytes, - * uint8_t *pucStreamBufferStorageArea, - * StaticStreamBuffer_t *pxStaticStreamBuffer ); + * size_t xTriggerLevelBytes, + * uint8_t *pucStreamBufferStorageArea, + * StaticStreamBuffer_t *pxStaticStreamBuffer ); * @endcode * Creates a new stream buffer using statically allocated memory. See * xStreamBufferCreate() for a version that uses dynamically allocated memory. * * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for - * xStreamBufferCreateStatic() to be available. + * xStreamBufferCreateStatic() to be available. configUSE_STREAM_BUFFERS must be + * set to 1 in for FreeRTOSConfig.h for xStreamBufferCreateStatic() to be + * available. * * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the * pucStreamBufferStorageArea parameter. @@ -253,11 +264,199 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf */ #define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BUFFER, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define xStreamBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ - xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BUFFER, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * stream_buffer.h + * + * @code{c} + * StreamBufferHandle_t xStreamBatchingBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes ); + * @endcode + * + * Creates a new stream batching buffer using dynamically allocated memory. See + * xStreamBatchingBufferCreateStatic() for a version that uses statically + * allocated memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBatchingBufferCreate() to be available. + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBatchingBufferCreate() to be available. + * + * The difference between a stream buffer and a stream batching buffer is when + * a task performs read on a non-empty buffer: + * - The task reading from a non-empty stream buffer returns immediately + * regardless of the amount of data in the buffer. + * - The task reading from a non-empty steam batching buffer blocks until the + * amount of data in the buffer exceeds the trigger level or the block time + * expires. + * + * @param xBufferSizeBytes The total number of bytes the stream batching buffer + * will be able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * batching buffer to unblock a task calling xStreamBufferReceive before the + * block time expires. + * + * @param pxSendCompletedCallback Callback invoked when number of bytes at least + * equal to trigger level is sent to the stream batching buffer. If the + * parameter is NULL, it will use the default implementation provided by + * sbSEND_COMPLETED macro. To enable the callback, configUSE_SB_COMPLETED_CALLBACK + * must be set to 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes + * are read from a stream batching buffer. If the parameter is NULL, it will use + * the default implementation provided by sbRECEIVE_COMPLETED macro. To enable + * the callback, configUSE_SB_COMPLETED_CALLBACK must be set to 1 in + * FreeRTOSConfig.h. + * + * @return If NULL is returned, then the stream batching buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream batching buffer data structures and storage area. A non-NULL value + * being returned indicates that the stream batching buffer has been created + * successfully - the returned value should be stored as the handle to the + * created stream batching buffer. + * + * Example use: + * @code{c} + * + * void vAFunction( void ) + * { + * StreamBufferHandle_t xStreamBatchingBuffer; + * const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10; + * + * // Create a stream batching buffer that can hold 100 bytes. The memory used + * // to hold both the stream batching buffer structure and the data in the stream + * // batching buffer is allocated dynamically. + * xStreamBatchingBuffer = xStreamBatchingBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); + * + * if( xStreamBatchingBuffer == NULL ) + * { + * // There was not enough heap memory space available to create the + * // stream batching buffer. + * } + * else + * { + * // The stream batching buffer was created successfully and can now be used. + * } + * } + * @endcode + * \defgroup xStreamBatchingBufferCreate xStreamBatchingBufferCreate + * \ingroup StreamBatchingBufferManagement + */ + +#define xStreamBatchingBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BATCHING_BUFFER, NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xStreamBatchingBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BATCHING_BUFFER, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * stream_buffer.h + * + * @code{c} + * StreamBufferHandle_t xStreamBatchingBufferCreateStatic( size_t xBufferSizeBytes, + * size_t xTriggerLevelBytes, + * uint8_t *pucStreamBufferStorageArea, + * StaticStreamBuffer_t *pxStaticStreamBuffer ); + * @endcode + * Creates a new stream batching buffer using statically allocated memory. See + * xStreamBatchingBufferCreate() for a version that uses dynamically allocated + * memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBatchingBufferCreateStatic() to be available. configUSE_STREAM_BUFFERS + * must be set to 1 in for FreeRTOSConfig.h for xStreamBatchingBufferCreateStatic() + * to be available. + * + * The difference between a stream buffer and a stream batching buffer is when + * a task performs read on a non-empty buffer: + * - The task reading from a non-empty stream buffer returns immediately + * regardless of the amount of data in the buffer. + * - The task reading from a non-empty steam batching buffer blocks until the + * amount of data in the buffer exceeds the trigger level or the block time + * expires. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * batching buffer to unblock a task calling xStreamBufferReceive before the + * block time expires. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes big. This is the array to which streams are + * copied when they are written to the stream batching buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream batching buffer's + * data structure. + * + * @param pxSendCompletedCallback Callback invoked when number of bytes at least + * equal to trigger level is sent to the stream batching buffer. If the parameter + * is NULL, it will use the default implementation provided by sbSEND_COMPLETED + * macro. To enable the callback, configUSE_SB_COMPLETED_CALLBACK must be set to + * 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes + * are read from a stream batching buffer. If the parameter is NULL, it will use + * the default implementation provided by sbRECEIVE_COMPLETED macro. To enable + * the callback, configUSE_SB_COMPLETED_CALLBACK must be set to 1 in + * FreeRTOSConfig.h. + * + * @return If the stream batching buffer is created successfully then a handle + * to the created stream batching buffer is returned. If either pucStreamBufferStorageArea + * or pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: + * @code{c} + * + * // Used to dimension the array used to hold the streams. The available space + * // will actually be one less than this, so 999. + * #define STORAGE_SIZE_BYTES 1000 + * + * // Defines the memory that will actually hold the streams within the stream + * // batching buffer. + * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; + * + * // The variable used to hold the stream batching buffer structure. + * StaticStreamBuffer_t xStreamBufferStruct; + * + * void MyFunction( void ) + * { + * StreamBufferHandle_t xStreamBatchingBuffer; + * const size_t xTriggerLevel = 1; + * + * xStreamBatchingBuffer = xStreamBatchingBufferCreateStatic( sizeof( ucStorageBuffer ), + * xTriggerLevel, + * ucStorageBuffer, + * &xStreamBufferStruct ); + * + * // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer + * // parameters were NULL, xStreamBatchingBuffer will not be NULL, and can be + * // used to reference the created stream batching buffer in other stream + * // buffer API calls. + * + * // Other code that uses the stream batching buffer can go here. + * } + * + * @endcode + * \defgroup xStreamBatchingBufferCreateStatic xStreamBatchingBufferCreateStatic + * \ingroup StreamBatchingBufferManagement + */ + +#define xStreamBatchingBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BATCHING_BUFFER, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xStreamBatchingBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), sbTYPE_STREAM_BATCHING_BUFFER, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) #endif /** @@ -273,6 +472,9 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf * buffer and storage area buffer. These are the same buffers that are supplied * at the time of creation. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferGetStaticBuffers() to be available. + * * @param xStreamBuffer The stream buffer for which to retrieve the buffers. * * @param ppucStreamBufferStorageArea Used to return a pointer to the stream @@ -297,9 +499,9 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf * * @code{c} * size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - * const void *pvTxData, - * size_t xDataLengthBytes, - * TickType_t xTicksToWait ); + * const void *pvTxData, + * size_t xDataLengthBytes, + * TickType_t xTicksToWait ); * @endcode * * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. @@ -312,17 +514,20 @@ typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuf * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xStreamBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xStreamBufferReceive()) inside a critical section and set the receive - * block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Use xStreamBufferSend() to write to a stream buffer from a task. Use * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt * service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferSend() to be available. + * * @param xStreamBuffer The handle of the stream buffer to which a stream is * being sent. * @@ -394,9 +599,9 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * * @code{c} * size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, - * const void *pvTxData, - * size_t xDataLengthBytes, - * BaseType_t *pxHigherPriorityTaskWoken ); + * const void *pvTxData, + * size_t xDataLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * Interrupt safe version of the API function that sends a stream of bytes to @@ -410,17 +615,20 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xStreamBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xStreamBufferReceive()) inside a critical section and set the receive - * block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Use xStreamBufferSend() to write to a stream buffer from a task. Use * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt * service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferSendFromISR() to be available. + * * @param xStreamBuffer The handle of the stream buffer to which a stream is * being sent. * @@ -495,9 +703,9 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * * @code{c} * size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - * void *pvRxData, - * size_t xBufferLengthBytes, - * TickType_t xTicksToWait ); + * void *pvRxData, + * size_t xBufferLengthBytes, + * TickType_t xTicksToWait ); * @endcode * * Receives bytes from a stream buffer. @@ -510,17 +718,20 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * writer and reader to be different tasks or interrupts, but, unlike other * FreeRTOS objects, it is not safe to have multiple different writers or * multiple different readers. If there are to be multiple different writers - * then the application writer must place each call to a writing API function - * (such as xStreamBufferSend()) inside a critical section and set the send - * block time to 0. Likewise, if there are to be multiple different readers - * then the application writer must place each call to a reading API function - * (such as xStreamBufferReceive()) inside a critical section and set the receive - * block time to 0. + * then the application writer must serialize calls to writing API functions + * (such as xStreamBufferSend()). Likewise, if there are to be multiple + * different readers then the application writer must serialize calls to reading + * API functions (such as xStreamBufferReceive()). One way to achieve such + * serialization in single core or SMP kernel is to place each API call inside a + * critical section and use a block time of 0. * * Use xStreamBufferReceive() to read from a stream buffer from a task. Use * xStreamBufferReceiveFromISR() to read from a stream buffer from an * interrupt service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferReceive() to be available. + * * @param xStreamBuffer The handle of the stream buffer from which bytes are to * be received. * @@ -584,9 +795,9 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * * @code{c} * size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, - * void *pvRxData, - * size_t xBufferLengthBytes, - * BaseType_t *pxHigherPriorityTaskWoken ); + * void *pvRxData, + * size_t xBufferLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); * @endcode * * An interrupt safe version of the API function that receives bytes from a @@ -596,6 +807,9 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an * interrupt service routine (ISR). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferReceiveFromISR() to be available. + * * @param xStreamBuffer The handle of the stream buffer from which a stream * is being received. * @@ -680,6 +894,9 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, * A stream buffer handle must not be used after the stream buffer has been * deleted. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * vStreamBufferDelete() to be available. + * * @param xStreamBuffer The handle of the stream buffer to be deleted. * * \defgroup vStreamBufferDelete vStreamBufferDelete @@ -697,6 +914,9 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI * Queries a stream buffer to see if it is full. A stream buffer is full if it * does not have any free space, and therefore cannot accept any more data. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferIsFull() to be available. + * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return If the stream buffer is full then pdTRUE is returned. Otherwise @@ -717,6 +937,9 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_ * Queries a stream buffer to see if it is empty. A stream buffer is empty if * it does not contain any data. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferIsEmpty() to be available. + * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return If the stream buffer is empty then pdTRUE is returned. Otherwise @@ -739,6 +962,13 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED * are no tasks blocked waiting to either send to or receive from the stream * buffer. * + * Use xStreamBufferReset() to reset a stream buffer from a task. + * Use xStreamBufferResetFromISR() to reset a stream buffer from an + * interrupt service routine (ISR). + * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferReset() to be available. + * * @param xStreamBuffer The handle of the stream buffer being reset. * * @return If the stream buffer is reset then pdPASS is returned. If there was @@ -750,6 +980,38 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED */ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * An interrupt safe version of the API function that resets the stream buffer. + * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * Use xStreamBufferReset() to reset a stream buffer from a task. + * Use xStreamBufferResetFromISR() to reset a stream buffer from an + * interrupt service routine (ISR). + * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferResetFromISR() to be available. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \defgroup xStreamBufferResetFromISR xStreamBufferResetFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + /** * stream_buffer.h * @@ -761,6 +1023,9 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F * equal to the amount of data that can be sent to the stream buffer before it * is full. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferSpacesAvailable() to be available. + * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return The number of bytes that can be written to the stream buffer before @@ -782,6 +1047,9 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL * the number of bytes that can be read from the stream buffer before the stream * buffer would be empty. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferBytesAvailable() to be available. + * * @param xStreamBuffer The handle of the stream buffer being queried. * * @return The number of bytes that can be read from the stream buffer before @@ -816,6 +1084,9 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILE * A trigger level is set when the stream buffer is created, and can be modified * using xStreamBufferSetTriggerLevel(). * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferSetTriggerLevel() to be available. + * * @param xStreamBuffer The handle of the stream buffer being updated. * * @param xTriggerLevel The new trigger level for the stream buffer. @@ -850,6 +1121,9 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferSendCompletedFromISR() to be available. + * * @param xStreamBuffer The handle of the stream buffer to which data was * written. * @@ -891,6 +1165,9 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for * additional information. * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * xStreamBufferReceiveCompletedFromISR() to be available. + * * @param xStreamBuffer The handle of the stream buffer from which data was * read. * @@ -911,17 +1188,74 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +/** + * stream_buffer.h + * + * @code{c} + * UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * Get the task notification index used for the supplied stream buffer which can + * be set using vStreamBufferSetStreamBufferNotificationIndex. If the task + * notification index for the stream buffer is not changed using + * vStreamBufferSetStreamBufferNotificationIndex, this function returns the + * default value (tskDEFAULT_INDEX_TO_NOTIFY). + * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * uxStreamBufferGetStreamBufferNotificationIndex() to be available. + * + * @param xStreamBuffer The handle of the stream buffer for which the task + * notification index is retrieved. + * + * @return The task notification index for the stream buffer. + * + * \defgroup uxStreamBufferGetStreamBufferNotificationIndex uxStreamBufferGetStreamBufferNotificationIndex + * \ingroup StreamBufferManagement + */ +UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * void vStreamBufferSetStreamBufferNotificationIndex ( StreamBuffer_t xStreamBuffer, UBaseType_t uxNotificationIndex ); + * @endcode + * + * Set the task notification index used for the supplied stream buffer. + * Successive calls to stream buffer APIs (like xStreamBufferSend or + * xStreamBufferReceive) for this stream buffer will use this new index for + * their task notifications. + * + * If this function is not called, the default index (tskDEFAULT_INDEX_TO_NOTIFY) + * is used for task notifications. It is recommended to call this function + * before attempting to send or receive data from the stream buffer to avoid + * inconsistencies. + * + * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for + * vStreamBufferSetStreamBufferNotificationIndex() to be available. + * + * @param xStreamBuffer The handle of the stream buffer for which the task + * notification index is set. + * + * @param uxNotificationIndex The task notification index to set. + * + * \defgroup vStreamBufferSetStreamBufferNotificationIndex vStreamBufferSetStreamBufferNotificationIndex + * \ingroup StreamBufferManagement + */ +void vStreamBufferSetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer, + UBaseType_t uxNotificationIndex ) PRIVILEGED_FUNCTION; + /* Functions below here are not part of the public API. */ StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, diff --git a/include/task.h b/include/task.h index 5a845f0ef..a25740e3b 100644 --- a/include/task.h +++ b/include/task.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -53,30 +53,33 @@ * The tskKERNEL_VERSION_MAJOR, tskKERNEL_VERSION_MINOR, tskKERNEL_VERSION_BUILD * values will reflect the last released version number. */ -#define tskKERNEL_VERSION_NUMBER "V10.4.4+" -#define tskKERNEL_VERSION_MAJOR 10 -#define tskKERNEL_VERSION_MINOR 4 -#define tskKERNEL_VERSION_BUILD 4 +#define tskKERNEL_VERSION_NUMBER "V11.1.0+" +#define tskKERNEL_VERSION_MAJOR 11 +#define tskKERNEL_VERSION_MINOR 1 +#define tskKERNEL_VERSION_BUILD 0 /* MPU region parameters passed in ulParameters * of MemoryRegion_t struct. */ -#define tskMPU_REGION_READ_ONLY ( 1UL << 0UL ) -#define tskMPU_REGION_READ_WRITE ( 1UL << 1UL ) -#define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL ) -#define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) -#define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) +#define tskMPU_REGION_READ_ONLY ( 1U << 0U ) +#define tskMPU_REGION_READ_WRITE ( 1U << 1U ) +#define tskMPU_REGION_EXECUTE_NEVER ( 1U << 2U ) +#define tskMPU_REGION_NORMAL_MEMORY ( 1U << 3U ) +#define tskMPU_REGION_DEVICE_MEMORY ( 1U << 4U ) +#if defined( portARMV8M_MINOR_VERSION ) && ( portARMV8M_MINOR_VERSION >= 1 ) + #define tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ( 1U << 5U ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ /* MPU region permissions stored in MPU settings to * authorize access requests. */ -#define tskMPU_READ_PERMISSION ( 1UL << 0UL ) -#define tskMPU_WRITE_PERMISSION ( 1UL << 1UL ) +#define tskMPU_READ_PERMISSION ( 1U << 0U ) +#define tskMPU_WRITE_PERMISSION ( 1U << 1U ) /* The direct to task notification feature used to have only a single notification * per task. Now there is an array of notifications per task that is dimensioned by * configTASK_NOTIFICATION_ARRAY_ENTRIES. For backward compatibility, any use of the * original direct to task notification defaults to using the first index in the * array. */ -#define tskDEFAULT_INDEX_TO_NOTIFY ( 0 ) +#define tskDEFAULT_INDEX_TO_NOTIFY ( 0 ) /** * task. h @@ -161,7 +164,7 @@ typedef struct xTASK_STATUS { TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ const char * pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ - UBaseType_t xTaskNumber; /* A number unique to the task. */ + UBaseType_t xTaskNumber; /* A number unique to the task. Note that this is not the task number that may be modified using vTaskSetTaskNumber() and uxTaskGetTaskNumber(), but a separate TCB-specific and unique identifier automatically assigned on task generation. */ eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ @@ -180,9 +183,10 @@ typedef struct xTASK_STATUS /* Possible return values for eTaskConfirmSleepModeStatus(). */ typedef enum { - eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPRESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ - eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPRESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep /* Enter a sleep mode that will not last any longer than the expected idle time. */ #if ( INCLUDE_vTaskSuspend == 1 ) + , eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ #endif /* INCLUDE_vTaskSuspend */ } eSleepModeStatus; @@ -288,8 +292,8 @@ typedef enum * @code{c} * BaseType_t xTaskCreate( * TaskFunction_t pxTaskCode, - * const char *pcName, - * configSTACK_DEPTH_TYPE usStackDepth, + * const char * const pcName, + * const configSTACK_DEPTH_TYPE uxStackDepth, * void *pvParameters, * UBaseType_t uxPriority, * TaskHandle_t *pxCreatedTask @@ -323,9 +327,9 @@ typedef enum * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default * is 16. * - * @param usStackDepth The size of the task stack specified as the number of + * @param uxStackDepth The size of the task stack specified as the number of * variables the stack can hold - not the number of bytes. For example, if - * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * the stack is 16 bits wide and uxStackDepth is defined as 100, 200 bytes * will be allocated for stack storage. * * @param pvParameters Pointer that will be used as the parameter for the task @@ -380,7 +384,7 @@ typedef enum #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, - const configSTACK_DEPTH_TYPE usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; @@ -389,7 +393,7 @@ typedef enum #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) BaseType_t xTaskCreateAffinitySet( TaskFunction_t pxTaskCode, const char * const pcName, - const configSTACK_DEPTH_TYPE usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, UBaseType_t uxCoreAffinityMask, @@ -400,8 +404,8 @@ typedef enum * task. h * @code{c} * TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, - * const char *pcName, - * uint32_t ulStackDepth, + * const char * const pcName, + * const configSTACK_DEPTH_TYPE uxStackDepth, * void *pvParameters, * UBaseType_t uxPriority, * StackType_t *puxStackBuffer, @@ -427,9 +431,9 @@ typedef enum * facilitate debugging. The maximum length of the string is defined by * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. * - * @param ulStackDepth The size of the task stack specified as the number of + * @param uxStackDepth The size of the task stack specified as the number of * variables the stack can hold - not the number of bytes. For example, if - * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * the stack is 32-bits wide and uxStackDepth is defined as 100 then 400 bytes * will be allocated for stack storage. * * @param pvParameters Pointer that will be used as the parameter for the task @@ -438,7 +442,7 @@ typedef enum * @param uxPriority The priority at which the task will run. * * @param puxStackBuffer Must point to a StackType_t array that has at least - * ulStackDepth indexes - the array will then be used as the task's stack, + * uxStackDepth indexes - the array will then be used as the task's stack, * removing the need for the stack to be allocated dynamically. * * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will @@ -472,7 +476,7 @@ typedef enum * { * // The parameter value is expected to be 1 as 1 is passed in the * // pvParameters value in the call to xTaskCreateStatic(). - * configASSERT( ( uint32_t ) pvParameters == 1UL ); + * configASSERT( ( uint32_t ) pvParameters == 1U ); * * for( ;; ) * { @@ -507,7 +511,7 @@ typedef enum #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -517,7 +521,7 @@ typedef enum #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) TaskHandle_t xTaskCreateStaticAffinitySet( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -561,9 +565,9 @@ typedef enum * { * vATask, // pvTaskCode - the function that implements the task. * "ATask", // pcName - just a text name for the task to assist debugging. - * 100, // usStackDepth - the stack size DEFINED IN WORDS. + * 100, // uxStackDepth - the stack size DEFINED IN WORDS. * NULL, // pvParameters - passed into the task function as the function parameters. - * ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. + * ( 1U | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. * cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack. * * // xRegions - Allocate up to three separate memory regions for access by @@ -655,9 +659,9 @@ typedef enum * { * vATask, // pvTaskCode - the function that implements the task. * "ATask", // pcName - just a text name for the task to assist debugging. - * 100, // usStackDepth - the stack size DEFINED IN WORDS. + * 100, // uxStackDepth - the stack size DEFINED IN WORDS. * NULL, // pvParameters - passed into the task function as the function parameters. - * ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. + * ( 1U | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. * cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack. * * // xRegions - Allocate up to three separate memory regions for access by @@ -1987,7 +1991,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /** * task.h * @code{c} - * void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) + * void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, configSTACK_DEPTH_TYPE * puxIdleTaskStackSize ) * @endcode * * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Idle Task TCB. This function is required when @@ -1995,16 +1999,16 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * * @param ppxIdleTaskTCBBuffer A handle to a statically allocated TCB buffer * @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task - * @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer + * @param puxIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer */ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, - uint32_t * pulIdleTaskStackSize ); + configSTACK_DEPTH_TYPE * puxIdleTaskStackSize ); /** * task.h * @code{c} - * void vApplicationGetPassiveIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize, BaseType_t xCoreID ) + * void vApplicationGetPassiveIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, configSTACK_DEPTH_TYPE * puxIdleTaskStackSize, BaseType_t xCoreID ) * @endcode * * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Idle Tasks TCB. This function is required when @@ -2022,13 +2026,13 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * * @param ppxIdleTaskTCBBuffer A handle to a statically allocated TCB buffer * @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task - * @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer + * @param puxIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer * @param xPassiveIdleTaskIndex The passive idle task index of the idle task buffer */ #if ( configNUMBER_OF_CORES > 1 ) void vApplicationGetPassiveIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, - uint32_t * pulIdleTaskStackSize, + configSTACK_DEPTH_TYPE * puxIdleTaskStackSize, BaseType_t xPassiveIdleTaskIndex ); #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ @@ -2138,7 +2142,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime ); * * // For percentage calculations. - * ulTotalRunTime /= 100UL; + * ulTotalRunTime /= 100U; * * // Avoid divide by zero errors. * if( ulTotalRunTime > 0 ) @@ -2152,7 +2156,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * // ulTotalRunTimeDiv100 has already been divided by 100. * ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime; * - * if( ulStatsAsPercentage > 0UL ) + * if( ulStatsAsPercentage > 0U ) * { * sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); * } @@ -2195,8 +2199,8 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * Lists all the current tasks, along with their current state and stack * usage high water mark. * - * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or - * suspended ('S'). + * Tasks are reported as running ('X'), blocked ('B'), ready ('R'), deleted ('D') + * or suspended ('S'). * * PLEASE NOTE: * @@ -2204,8 +2208,16 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * demo applications. Do not consider it to be part of the scheduler. * * vTaskListTasks() calls uxTaskGetSystemState(), then formats part of the - * uxTaskGetSystemState() output into a human readable table that displays task: - * names, states, priority, stack usage and task number. + * uxTaskGetSystemState() output into a human readable table that displays task + * information in the following format: + * Task Name, Task State, Task Priority, Task Stack High Watermak, Task Number. + * + * The following is a sample output: + * Task A X 2 67 2 + * Task B R 1 67 3 + * IDLE R 0 67 5 + * Tmr Svc B 6 137 6 + * * Stack usage specified as the number of unused StackType_t words stack can hold * on top of stack - not the number of bytes. * @@ -2256,8 +2268,8 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * Lists all the current tasks, along with their current state and stack * usage high water mark. * - * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or - * suspended ('S'). + * Tasks are reported as running ('X'), blocked ('B'), ready ('R'), deleted ('D') + * or suspended ('S'). * * PLEASE NOTE: * @@ -2265,8 +2277,16 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * demo applications. Do not consider it to be part of the scheduler. * * vTaskList() calls uxTaskGetSystemState(), then formats part of the - * uxTaskGetSystemState() output into a human readable table that displays task: - * names, states, priority, stack usage and task number. + * uxTaskGetSystemState() output into a human readable table that displays task + * information in the following format: + * Task Name, Task State, Task Priority, Task Stack High Watermak, Task Number. + * + * The following is a sample output: + * Task A X 2 67 2 + * Task B R 1 67 3 + * IDLE R 0 67 5 + * Tmr Svc B 6 137 6 + * * Stack usage specified as the number of unused StackType_t words stack can hold * on top of stack - not the number of bytes. * @@ -2289,7 +2309,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * \defgroup vTaskList vTaskList * \ingroup TaskUtils */ -#define vTaskList( pcWriteBuffer ) vTaskListTasks( pcWriteBuffer, configSTATS_BUFFER_MAX_LENGTH ) +#define vTaskList( pcWriteBuffer ) vTaskListTasks( ( pcWriteBuffer ), configSTATS_BUFFER_MAX_LENGTH ) /** * task. h @@ -2368,7 +2388,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * * WARN: This function assumes that the pcWriteBuffer is of length * configSTATS_BUFFER_MAX_LENGTH. This function is there only for - * backward compatiblity. New applications are recommended to use + * backward compatibility. New applications are recommended to use * vTaskGetRunTimeStatistics and supply the length of the pcWriteBuffer * explicitly. * @@ -2412,7 +2432,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats * \ingroup TaskUtils */ -#define vTaskGetRunTimeStats( pcWriteBuffer ) vTaskGetRunTimeStatistics( pcWriteBuffer, configSTATS_BUFFER_MAX_LENGTH ) +#define vTaskGetRunTimeStats( pcWriteBuffer ) vTaskGetRunTimeStatistics( ( pcWriteBuffer ), configSTATS_BUFFER_MAX_LENGTH ) /** * task. h @@ -2862,7 +2882,7 @@ BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, * will be cleared in the calling task's notification value before the task * checks to see if any notifications are pending, and optionally blocks if no * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if - * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * limits.h is included) or 0xffffffffU (if limits.h is not included) will have * the effect of resetting the task's notification value to 0. Setting * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. * @@ -3438,6 +3458,20 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, */ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; +/** + * task.h + * @code{c} + * void vTaskResetState( void ); + * @endcode + * + * This function resets the internal state of the task. It must be called by the + * application before restarting the scheduler. + * + * \defgroup vTaskResetState vTaskResetState + * \ingroup SchedulerControl + */ +void vTaskResetState( void ) PRIVILEGED_FUNCTION; + /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES @@ -3574,9 +3608,7 @@ TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; /* * Return the handle of the task running on specified core. */ -#if ( configNUMBER_OF_CORES > 1 ) - TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID ) PRIVILEGED_FUNCTION; -#endif +TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID ) PRIVILEGED_FUNCTION; /* * Shortcut used by the queue implementation to prevent unnecessary call to diff --git a/include/timers.h b/include/timers.h index e874d2434..7d99d3536 100644 --- a/include/timers.h +++ b/include/timers.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -737,14 +737,18 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; * // The key press event handler. * void vKeyPressEventHandler( char cKey ) * { - * // Ensure the LCD back-light is on, then reset the timer that is - * // responsible for turning the back-light off after 5 seconds of - * // key inactivity. Wait 10 ticks for the command to be successfully sent - * // if it cannot be sent immediately. - * vSetBacklightState( BACKLIGHT_ON ); - * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * // Reset the timer that is responsible for turning the back-light off after + * // 5 seconds of key inactivity. Wait 10 ticks for the command to be + * // successfully sent if it cannot be sent immediately. + * if( xTimerReset( xBacklightTimer, 10 ) == pdPASS ) * { - * // The reset command was not executed successfully. Take appropriate + * // Turn on the LCD back-light. It will be turned off in the + * // vBacklightTimerCallback after 5 seconds of key inactivity. + * vSetBacklightState( BACKLIGHT_ON ); + * } + * else + * { + * // The reset command was not executed successfully. Take appropriate * // action here. * } * @@ -753,16 +757,15 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; * * void main( void ) * { - * int32_t x; * * // Create then start the one-shot timer that is responsible for turning * // the back-light off if no keys are pressed within a 5 second period. * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. - * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdMS_TO_TICKS( 5000 ), // The timer period in ticks. * pdFALSE, // The timer is a one-shot timer. * 0, // The id is not used by the callback so can take any value. * vBacklightTimerCallback // The callback function that switches the LCD back-light off. - * ); + * ); * * if( xBacklightTimer == NULL ) * { @@ -1384,7 +1387,7 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer, /** * task.h * @code{c} - * void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) + * void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, configSTACK_DEPTH_TYPE * puxTimerTaskStackSize ) * @endcode * * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Timer Task TCB. This function is required when @@ -1392,11 +1395,11 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer, * * @param ppxTimerTaskTCBBuffer A handle to a statically allocated TCB buffer * @param ppxTimerTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task - * @param pulTimerTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer + * @param puxTimerTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer */ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, - uint32_t * pulTimerTaskStackSize ); + configSTACK_DEPTH_TYPE * puxTimerTaskStackSize ); #endif @@ -1417,6 +1420,12 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer, #endif +/* + * This function resets the internal state of the timer module. It must be called + * by the application before restarting the scheduler. + */ +void vTimerResetState( void ) PRIVILEGED_FUNCTION; + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/list.c b/list.c index 907300896..0c0f3676e 100644 --- a/list.c +++ b/list.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -130,7 +130,7 @@ void vListInsertEnd( List_t * const pxList, /* Remember which list the item is in. */ pxNewListItem->pxContainer = pxList; - ( pxList->uxNumberOfItems )++; + ( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U ); traceRETURN_vListInsertEnd(); } @@ -166,7 +166,7 @@ void vListInsert( List_t * const pxList, { /* *** NOTE *********************************************************** * If you find your application is crashing here then likely causes are - * listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for + * listed below. In addition see https://www.freertos.org/Why-FreeRTOS/FAQs for * more tips, and ensure configASSERT() is defined! * https://www.FreeRTOS.org/a00110.html#configASSERT * @@ -192,7 +192,9 @@ void vListInsert( List_t * const pxList, for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) { /* There is nothing to do here, just iterating to the wanted - * insertion position. */ + * insertion position. + * IF YOU FIND YOUR CODE STUCK HERE, SEE THE NOTE JUST ABOVE. + */ } } @@ -205,12 +207,13 @@ void vListInsert( List_t * const pxList, * item later. */ pxNewListItem->pxContainer = pxList; - ( pxList->uxNumberOfItems )++; + ( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U ); traceRETURN_vListInsert(); } /*-----------------------------------------------------------*/ + UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) { /* The list item knows which list it is in. Obtain the list from the list @@ -219,8 +222,6 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) traceENTER_uxListRemove( pxItemToRemove ); - - pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; @@ -238,7 +239,7 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) } pxItemToRemove->pxContainer = NULL; - ( pxList->uxNumberOfItems )--; + ( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems - 1U ); traceRETURN_uxListRemove( pxList->uxNumberOfItems ); diff --git a/manifest.yml b/manifest.yml index 211e3c2ae..bd893f162 100644 --- a/manifest.yml +++ b/manifest.yml @@ -1,4 +1,4 @@ name : "FreeRTOS-Kernel" -version: "v10.5.1" +version: "V11.0.1+" description: "FreeRTOS Kernel." license: "MIT" diff --git a/portable/ARMv8M/copy_files.py b/portable/ARMv8M/copy_files.py index 3609c67ef..023fb68e0 100644 --- a/portable/ARMv8M/copy_files.py +++ b/portable/ARMv8M/copy_files.py @@ -1,6 +1,6 @@ #/* # * FreeRTOS Kernel -# * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # * # * SPDX-License-Identifier: MIT # * diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c index e67f3cbae..7a62caff0 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -63,12 +63,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -93,12 +92,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -123,12 +121,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -153,12 +150,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -183,12 +179,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0, r1} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -219,12 +214,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -249,12 +243,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -279,12 +272,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -309,12 +301,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -337,12 +328,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -363,12 +353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -391,12 +380,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -421,12 +409,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -451,12 +438,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -481,12 +467,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -513,12 +498,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -543,12 +527,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -577,12 +560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -609,12 +591,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -643,12 +624,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -673,12 +653,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -703,12 +682,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -733,12 +711,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -763,12 +740,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -791,12 +767,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -819,12 +794,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -847,12 +821,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -877,12 +850,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -911,12 +883,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -943,12 +914,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -977,12 +947,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -1011,12 +980,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1037,12 +1005,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1063,12 +1030,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1093,12 +1059,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1123,12 +1088,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1151,12 +1115,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1179,12 +1142,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1211,12 +1173,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1241,12 +1202,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1273,12 +1233,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1305,12 +1264,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1337,12 +1295,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1367,12 +1324,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1397,12 +1353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1427,12 +1382,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1459,12 +1413,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1489,12 +1442,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1519,12 +1471,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1542,21 +1493,20 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1579,12 +1529,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1597,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1611,12 +1560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1641,12 +1589,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1671,12 +1618,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1701,12 +1647,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1731,12 +1676,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1746,121 +1690,133 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1875,22 +1831,21 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1907,241 +1862,264 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c index f8b37b691..978d35259 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -56,11 +56,11 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -68,34 +68,34 @@ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -103,7 +103,7 @@ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" @@ -114,7 +114,7 @@ " msr psp, r3 \n" " msr control, r5 \n" " mov lr, r6 \n" - " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " \n" " restore_general_regs_first_task: \n" @@ -136,14 +136,6 @@ " restore_context_done_first_task: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xSecureContextConst2: .word xSecureContext \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -155,12 +147,12 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" + " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " movs r1, #2 \n" /* r1 = 2. */ " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ @@ -168,10 +160,6 @@ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " bx r3 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - "xSecureContextConst2: .word xSecureContext \n" ); } @@ -193,8 +181,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " running_privileged: \n" " movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "r1", "memory" ); } @@ -238,7 +224,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -247,9 +233,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -292,9 +275,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ " \n" @@ -337,11 +320,11 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " cpsie i \n" " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -349,34 +332,34 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -384,7 +367,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" @@ -395,7 +378,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr psp, r3 \n" " msr control, r5 \n" " mov lr, r6 \n" - " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " cbz r0, restore_ns_context \n" /* No secure context to restore. */ " \n" @@ -429,14 +412,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xSecureContextConst: .word xSecureContext \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ); } @@ -450,9 +425,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ " mrs r2, psp \n" /* Read PSP in r2. */ " \n" @@ -463,7 +438,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov lr, r3 \n" /* LR = r3. */ " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -473,7 +448,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " b select_next_task \n" " \n" " save_ns_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -491,16 +466,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " bl vTaskSwitchContext \n" " cpsie i \n" " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " mov lr, r4 \n" /* LR = r4. */ - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r3] \n" /* Restore the task's xSecureContext. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ @@ -522,10 +497,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " subs r2, r2, #32 \n" /* Go back to the low registers. */ " ldmia r2!, {r4-r7} \n" /* Restore the low registers that are not automatically restored. */ " bx lr \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - "xSecureContextConst: .word xSecureContext \n" ); } @@ -588,15 +559,12 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h index 33d522488..e81b89228 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c index e67f3cbae..7a62caff0 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -63,12 +63,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -93,12 +92,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -123,12 +121,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -153,12 +150,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -183,12 +179,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0, r1} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -219,12 +214,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -249,12 +243,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -279,12 +272,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -309,12 +301,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -337,12 +328,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -363,12 +353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -391,12 +380,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -421,12 +409,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -451,12 +438,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -481,12 +467,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -513,12 +498,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -543,12 +527,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -577,12 +560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -609,12 +591,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -643,12 +624,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -673,12 +653,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -703,12 +682,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -733,12 +711,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -763,12 +740,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -791,12 +767,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -819,12 +794,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -847,12 +821,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -877,12 +850,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -911,12 +883,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -943,12 +914,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -977,12 +947,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -1011,12 +980,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1037,12 +1005,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1063,12 +1030,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1093,12 +1059,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1123,12 +1088,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1151,12 +1115,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1179,12 +1142,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1211,12 +1173,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1241,12 +1202,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1273,12 +1233,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1305,12 +1264,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1337,12 +1295,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1367,12 +1324,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1397,12 +1353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1427,12 +1382,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1459,12 +1413,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1489,12 +1442,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1519,12 +1471,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1542,21 +1493,20 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1579,12 +1529,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1597,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1611,12 +1560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1641,12 +1589,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1671,12 +1618,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1701,12 +1647,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1731,12 +1676,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1746,121 +1690,133 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1875,22 +1831,21 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1907,241 +1862,264 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c index 5fde8342e..d215f8f73 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -56,11 +56,11 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -68,34 +68,34 @@ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -103,7 +103,7 @@ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -137,13 +137,6 @@ " restore_context_done_first_task: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -155,7 +148,7 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" @@ -169,9 +162,6 @@ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " bx r2 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -193,8 +183,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " running_privileged: \n" " movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "r1", "memory" ); } @@ -238,7 +226,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -247,9 +235,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -290,7 +275,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ " mrs r2, psp \n" /* r2 = PSP. */ @@ -325,11 +310,11 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " cpsie i \n" " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -337,34 +322,34 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -372,7 +357,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -406,13 +391,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ); } @@ -425,7 +403,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .syntax unified \n" " \n" " mrs r0, psp \n" /* Read PSP in r0. */ - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -446,7 +424,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " bl vTaskSwitchContext \n" " cpsie i \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" @@ -463,9 +441,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ #endif " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ); } @@ -528,15 +503,12 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h index 33d522488..e81b89228 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c index 4cb310afd..33410a0c3 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,130 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1771,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1801,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c index 16c598ad7..0ebbe48a4 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,57 +54,65 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " \n" " restore_general_regs_first_task: \n" @@ -115,14 +125,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xSecureContextConst2: .word xSecureContext \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -134,25 +136,32 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" + " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n" /* Finally, branch to EXC_RETURN. */ - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - "xSecureContextConst2: .word xSecureContext \n" ); } @@ -171,8 +180,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -214,7 +221,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -224,9 +231,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -240,7 +244,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -274,9 +278,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ " \n" @@ -293,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -313,11 +315,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -325,57 +335,65 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " cbz r0, restore_ns_context \n" /* No secure context to restore. */ " \n" @@ -393,25 +411,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xSecureContextConst: .word xSecureContext \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -422,93 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " b select_next_task \n" - " \n" - " save_ns_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n" /* LR = r4. */ - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - "xSecureContextConst: .word xSecureContext \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -566,11 +582,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h index 227327ac8..2d435ca0b 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -57,6 +58,13 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c index 4cb310afd..4b984932d 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,129 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1770,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1800,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c index 76ba642a0..bc7bb6071 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,52 +54,60 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -113,13 +123,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -131,23 +134,30 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -166,8 +176,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -209,7 +217,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -219,9 +227,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -235,7 +240,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -267,22 +272,21 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -291,11 +295,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -303,52 +315,60 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -358,24 +378,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -390,46 +403,61 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -487,11 +515,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h index 227327ac8..2d435ca0b 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -57,6 +58,13 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h index 66fa2056d..b886287ac 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -57,6 +58,13 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h index 7b011b5b5..c6a179c52 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h index a6fda8a88..7e14f2696 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S index 419df5b1e..9289bcbc2 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -48,12 +48,11 @@ MPU_xTaskDelayUntil: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0, r1} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -63,12 +62,11 @@ MPU_xTaskAbortDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0, r1} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -78,12 +76,11 @@ MPU_vTaskDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0, r1} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -93,12 +90,11 @@ MPU_uxTaskPriorityGet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0, r1} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -108,12 +104,11 @@ MPU_eTaskGetState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0, r1} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -123,12 +118,11 @@ MPU_vTaskGetInfo: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0, r1} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -138,12 +132,11 @@ MPU_xTaskGetIdleTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -153,12 +146,11 @@ MPU_vTaskSuspend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0, r1} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -168,12 +160,11 @@ MPU_vTaskResume: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0, r1} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -183,12 +174,11 @@ MPU_xTaskGetTickCount: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0, r1} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -198,12 +188,11 @@ MPU_uxTaskGetNumberOfTasks: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0, r1} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -213,12 +202,11 @@ MPU_ulTaskGetRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -228,12 +216,11 @@ MPU_ulTaskGetRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +230,11 @@ MPU_ulTaskGetIdleRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -258,12 +244,11 @@ MPU_ulTaskGetIdleRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -273,12 +258,11 @@ MPU_vTaskSetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -288,12 +272,11 @@ MPU_xTaskGetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -303,12 +286,11 @@ MPU_vTaskSetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -318,12 +300,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -333,12 +314,11 @@ MPU_uxTaskGetSystemState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0, r1} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -348,12 +328,11 @@ MPU_uxTaskGetStackHighWaterMark: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -363,12 +342,11 @@ MPU_uxTaskGetStackHighWaterMark2: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -378,12 +356,11 @@ MPU_xTaskGetCurrentTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -393,12 +370,11 @@ MPU_xTaskGetSchedulerState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0, r1} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -408,12 +384,11 @@ MPU_vTaskSetTimeOutState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0, r1} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -423,12 +398,11 @@ MPU_xTaskCheckForTimeOut: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0, r1} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -438,12 +412,11 @@ MPU_xTaskGenericNotifyEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -453,12 +426,11 @@ MPU_xTaskGenericNotifyWaitEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -468,12 +440,11 @@ MPU_ulTaskGenericNotifyTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -483,12 +454,11 @@ MPU_xTaskGenericNotifyStateClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -498,12 +468,11 @@ MPU_ulTaskGenericNotifyValueClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -513,12 +482,11 @@ MPU_xQueueGenericSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0, r1} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -528,12 +496,11 @@ MPU_uxQueueMessagesWaiting: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0, r1} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -543,12 +510,11 @@ MPU_uxQueueSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0, r1} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -558,12 +524,11 @@ MPU_xQueueReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0, r1} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -573,12 +538,11 @@ MPU_xQueuePeek: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0, r1} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -588,12 +552,11 @@ MPU_xQueueSemaphoreTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0, r1} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -603,12 +566,11 @@ MPU_xQueueGetMutexHolder: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0, r1} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -618,12 +580,11 @@ MPU_xQueueTakeMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -633,12 +594,11 @@ MPU_xQueueGiveMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -648,12 +608,11 @@ MPU_xQueueSelectFromSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0, r1} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -663,12 +622,11 @@ MPU_xQueueAddToSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0, r1} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -678,12 +636,11 @@ MPU_vQueueAddToRegistry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0, r1} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -693,12 +650,11 @@ MPU_vQueueUnregisterQueue: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0, r1} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -708,12 +664,11 @@ MPU_pcQueueGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0, r1} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -723,12 +678,11 @@ MPU_pvTimerGetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0, r1} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -738,12 +692,11 @@ MPU_vTimerSetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0, r1} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -753,12 +706,11 @@ MPU_xTimerIsTimerActive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0, r1} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -768,12 +720,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0, r1} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -783,12 +734,11 @@ MPU_xTimerGenericCommandFromTaskEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0, r1} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -798,12 +748,11 @@ MPU_pcTimerGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0, r1} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -813,12 +762,11 @@ MPU_vTimerSetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0, r1} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -828,12 +776,11 @@ MPU_xTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -843,12 +790,11 @@ MPU_uxTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -858,12 +804,11 @@ MPU_xTimerGetPeriod: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0, r1} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -873,12 +818,11 @@ MPU_xTimerGetExpiryTime: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0, r1} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -888,12 +832,11 @@ MPU_xEventGroupWaitBitsEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0, r1} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -903,12 +846,11 @@ MPU_xEventGroupClearBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0, r1} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -918,12 +860,11 @@ MPU_xEventGroupSetBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0, r1} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -933,12 +874,11 @@ MPU_xEventGroupSync: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0, r1} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -948,12 +888,11 @@ MPU_uxEventGroupGetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0, r1} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -963,12 +902,11 @@ MPU_vEventGroupSetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0, r1} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -978,12 +916,11 @@ MPU_xStreamBufferSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0, r1} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -993,12 +930,11 @@ MPU_xStreamBufferReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0, r1} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -1008,12 +944,11 @@ MPU_xStreamBufferIsFull: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0, r1} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -1023,12 +958,11 @@ MPU_xStreamBufferIsEmpty: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0, r1} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -1038,12 +972,11 @@ MPU_xStreamBufferSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -1053,12 +986,11 @@ MPU_xStreamBufferBytesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -1068,12 +1000,11 @@ MPU_xStreamBufferSetTriggerLevel: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0, r1} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1083,12 +1014,11 @@ MPU_xStreamBufferNextMessageLengthBytes: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0, r1} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s index 06c761090..6817abd7a 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h index e426f5b9a..9d6c3368e 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S index 419df5b1e..9289bcbc2 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -48,12 +48,11 @@ MPU_xTaskDelayUntil: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0, r1} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -63,12 +62,11 @@ MPU_xTaskAbortDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0, r1} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -78,12 +76,11 @@ MPU_vTaskDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0, r1} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -93,12 +90,11 @@ MPU_uxTaskPriorityGet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0, r1} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -108,12 +104,11 @@ MPU_eTaskGetState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0, r1} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -123,12 +118,11 @@ MPU_vTaskGetInfo: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0, r1} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -138,12 +132,11 @@ MPU_xTaskGetIdleTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -153,12 +146,11 @@ MPU_vTaskSuspend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0, r1} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -168,12 +160,11 @@ MPU_vTaskResume: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0, r1} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -183,12 +174,11 @@ MPU_xTaskGetTickCount: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0, r1} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -198,12 +188,11 @@ MPU_uxTaskGetNumberOfTasks: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0, r1} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -213,12 +202,11 @@ MPU_ulTaskGetRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -228,12 +216,11 @@ MPU_ulTaskGetRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +230,11 @@ MPU_ulTaskGetIdleRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -258,12 +244,11 @@ MPU_ulTaskGetIdleRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -273,12 +258,11 @@ MPU_vTaskSetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -288,12 +272,11 @@ MPU_xTaskGetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -303,12 +286,11 @@ MPU_vTaskSetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -318,12 +300,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -333,12 +314,11 @@ MPU_uxTaskGetSystemState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0, r1} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -348,12 +328,11 @@ MPU_uxTaskGetStackHighWaterMark: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -363,12 +342,11 @@ MPU_uxTaskGetStackHighWaterMark2: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -378,12 +356,11 @@ MPU_xTaskGetCurrentTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -393,12 +370,11 @@ MPU_xTaskGetSchedulerState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0, r1} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -408,12 +384,11 @@ MPU_vTaskSetTimeOutState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0, r1} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -423,12 +398,11 @@ MPU_xTaskCheckForTimeOut: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0, r1} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -438,12 +412,11 @@ MPU_xTaskGenericNotifyEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -453,12 +426,11 @@ MPU_xTaskGenericNotifyWaitEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -468,12 +440,11 @@ MPU_ulTaskGenericNotifyTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -483,12 +454,11 @@ MPU_xTaskGenericNotifyStateClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -498,12 +468,11 @@ MPU_ulTaskGenericNotifyValueClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -513,12 +482,11 @@ MPU_xQueueGenericSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0, r1} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -528,12 +496,11 @@ MPU_uxQueueMessagesWaiting: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0, r1} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -543,12 +510,11 @@ MPU_uxQueueSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0, r1} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -558,12 +524,11 @@ MPU_xQueueReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0, r1} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -573,12 +538,11 @@ MPU_xQueuePeek: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0, r1} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -588,12 +552,11 @@ MPU_xQueueSemaphoreTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0, r1} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -603,12 +566,11 @@ MPU_xQueueGetMutexHolder: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0, r1} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -618,12 +580,11 @@ MPU_xQueueTakeMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -633,12 +594,11 @@ MPU_xQueueGiveMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -648,12 +608,11 @@ MPU_xQueueSelectFromSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0, r1} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -663,12 +622,11 @@ MPU_xQueueAddToSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0, r1} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -678,12 +636,11 @@ MPU_vQueueAddToRegistry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0, r1} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -693,12 +650,11 @@ MPU_vQueueUnregisterQueue: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0, r1} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -708,12 +664,11 @@ MPU_pcQueueGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0, r1} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -723,12 +678,11 @@ MPU_pvTimerGetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0, r1} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -738,12 +692,11 @@ MPU_vTimerSetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0, r1} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -753,12 +706,11 @@ MPU_xTimerIsTimerActive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0, r1} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -768,12 +720,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0, r1} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -783,12 +734,11 @@ MPU_xTimerGenericCommandFromTaskEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0, r1} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -798,12 +748,11 @@ MPU_pcTimerGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0, r1} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -813,12 +762,11 @@ MPU_vTimerSetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0, r1} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -828,12 +776,11 @@ MPU_xTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -843,12 +790,11 @@ MPU_uxTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -858,12 +804,11 @@ MPU_xTimerGetPeriod: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0, r1} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -873,12 +818,11 @@ MPU_xTimerGetExpiryTime: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0, r1} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -888,12 +832,11 @@ MPU_xEventGroupWaitBitsEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0, r1} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -903,12 +846,11 @@ MPU_xEventGroupClearBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0, r1} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -918,12 +860,11 @@ MPU_xEventGroupSetBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0, r1} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -933,12 +874,11 @@ MPU_xEventGroupSync: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0, r1} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -948,12 +888,11 @@ MPU_uxEventGroupGetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0, r1} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -963,12 +902,11 @@ MPU_vEventGroupSetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0, r1} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -978,12 +916,11 @@ MPU_xStreamBufferSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0, r1} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -993,12 +930,11 @@ MPU_xStreamBufferReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0, r1} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -1008,12 +944,11 @@ MPU_xStreamBufferIsFull: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0, r1} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -1023,12 +958,11 @@ MPU_xStreamBufferIsEmpty: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0, r1} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -1038,12 +972,11 @@ MPU_xStreamBufferSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -1053,12 +986,11 @@ MPU_xStreamBufferBytesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -1068,12 +1000,11 @@ MPU_xStreamBufferSetTriggerLevel: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0, r1} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1083,12 +1014,11 @@ MPU_xStreamBufferNextMessageLengthBytes: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0, r1} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s index d4487dfac..bfe9eee4b 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h index e426f5b9a..9d6c3368e 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s index d8f1b1d9a..8d5988819 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -150,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -175,12 +185,22 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +233,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -268,11 +288,20 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -326,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -371,76 +408,86 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - mov lr, r4 /* LR = r4. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h index a707fc658..53b668b5b 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,18 +50,21 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /* ARMv8-M common port configurations. */ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s index 7cf467d22..ba6e8e915 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -140,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -163,10 +173,20 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +219,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -230,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -239,11 +258,20 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -297,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -332,12 +368,21 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ +#if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -348,6 +393,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h index 64d39e3b9..53b668b5b 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -57,8 +58,10 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h index 82bfaeb79..6e543efb5 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -57,8 +58,10 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h index 1338d25be..597af66fa 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -62,11 +63,6 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /** * @brief Critical section management. */ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h index cffcb20d9..ff5c9895d 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -62,11 +63,6 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /** * @brief Critical section management. */ diff --git a/portable/ARMv8M/non_secure/portasm.h b/portable/ARMv8M/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/ARMv8M/non_secure/portasm.h +++ b/portable/ARMv8M/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c index 2d9eeeaf8..32559ad04 100644 --- a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c +++ b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c index 13520870b..2d3d9439d 100644 --- a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c +++ b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s index f7c5d19d2..f70e89115 100644 --- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s +++ b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s index 400bd0107..27a8f3933 100644 --- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s +++ b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/ARMv8M/secure/context/secure_context.c +++ b/portable/ARMv8M/secure/context/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/ARMv8M/secure/context/secure_context.h b/portable/ARMv8M/secure/context/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/ARMv8M/secure/context/secure_context.h +++ b/portable/ARMv8M/secure/context/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/heap/secure_heap.c b/portable/ARMv8M/secure/heap/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/ARMv8M/secure/heap/secure_heap.c +++ b/portable/ARMv8M/secure/heap/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/ARMv8M/secure/heap/secure_heap.h b/portable/ARMv8M/secure/heap/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/ARMv8M/secure/heap/secure_heap.h +++ b/portable/ARMv8M/secure/heap/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/init/secure_init.c b/portable/ARMv8M/secure/init/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/ARMv8M/secure/init/secure_init.c +++ b/portable/ARMv8M/secure/init/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/init/secure_init.h b/portable/ARMv8M/secure/init/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/ARMv8M/secure/init/secure_init.h +++ b/portable/ARMv8M/secure/init/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ARMv8M/secure/macros/secure_port_macros.h b/portable/ARMv8M/secure/macros/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/ARMv8M/secure/macros/secure_port_macros.h +++ b/portable/ARMv8M/secure/macros/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/BCC/16BitDOS/Flsh186/port.c b/portable/BCC/16BitDOS/Flsh186/port.c index 66b8b7b7b..14b1f6f5a 100644 --- a/portable/BCC/16BitDOS/Flsh186/port.c +++ b/portable/BCC/16BitDOS/Flsh186/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/BCC/16BitDOS/Flsh186/prtmacro.h b/portable/BCC/16BitDOS/Flsh186/prtmacro.h index 295c0bc73..b1b5c26eb 100644 --- a/portable/BCC/16BitDOS/Flsh186/prtmacro.h +++ b/portable/BCC/16BitDOS/Flsh186/prtmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/BCC/16BitDOS/PC/port.c b/portable/BCC/16BitDOS/PC/port.c index 6940b1a67..0c1c0644e 100644 --- a/portable/BCC/16BitDOS/PC/port.c +++ b/portable/BCC/16BitDOS/PC/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/BCC/16BitDOS/PC/prtmacro.h b/portable/BCC/16BitDOS/PC/prtmacro.h index 5fb4ed6a4..d24431806 100644 --- a/portable/BCC/16BitDOS/PC/prtmacro.h +++ b/portable/BCC/16BitDOS/PC/prtmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/BCC/16BitDOS/common/portasm.h b/portable/BCC/16BitDOS/common/portasm.h index e53d257c8..3e3acf0bd 100644 --- a/portable/BCC/16BitDOS/common/portasm.h +++ b/portable/BCC/16BitDOS/common/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/BCC/16BitDOS/common/portcomn.c b/portable/BCC/16BitDOS/common/portcomn.c index 69ab45ba7..0e1bca1ab 100644 --- a/portable/BCC/16BitDOS/common/portcomn.c +++ b/portable/BCC/16BitDOS/common/portcomn.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CCRH/F1Kx/README.md b/portable/CCRH/F1Kx/README.md new file mode 100644 index 000000000..4cb9f07b6 --- /dev/null +++ b/portable/CCRH/F1Kx/README.md @@ -0,0 +1,46 @@ +# RH850/F1K and F1Kx FreeRTOS Port with CC-RH Compiler + +## Introduction + +This repository contains the port of FreeRTOS for Renesas RH850/F1K and F1Kx microcontrollers using the CC-RH compiler. The following sections provide instructions on how to use this port, a link to the test project, and other relevant information. + +## Prerequisites +- Compiler: CC-RH +- FreeRTOS version 11.1.0 + +| Device | FPU | SMP | +|----------|-----|-----| +| F1K | Yes | No | +| F1KM-S1 | Yes | No | +| F1KM-S2 | Yes | No | +| F1KM-S4 | Yes | No | +| F1KH-D8 | Yes | Yes | + +## Link to Test Project + +The test project can be found [here](https://github.com/FreeRTOS/FreeRTOS-Community-Supported-Demos) (`RH850_F1Kx_CCRH`). This project contains example tasks and configurations to help you get started with FreeRTOS on the RH850/F1K and F1Kx. + +## Note + 1. Configure IPIR Interrupt: Ensure that the bit specifying the destination for binding (requesting) an interrupt is enabled (e.g: IBDxxx register of F1KH-D8) (1) + 2. `Channel 0` and address `0xFFFEEC00` are used as default configuration for configIPIR_CHANNEL and configEXCLUSIVE_ADDRESS, in case of resource confliction other channel/address can be used. (2) + 3. The minimal stack size (configMINIMAL_STACK_SIZE) must be included the reserved memory for nested interrupt. This formula can be referred: `(task_context_size) * (2 + configMAX_INT_NESTING) + Stack_depth_of_taskcode` + In which, `task_context_size` is calculated as `36*4bytes = 144bytes` (when FPU enabled) or `34*4bytes = 136` (when FPU disabled), configMAX_INT_NESTING is `02` as default (Note that a value of `0` is not allowed). + 4. `configTIMER_PRESCALE`: This value is required in order to correctly configure clock for `CPUCLK_L`. Refer to Hardware Manual at `Table 44.22` for `option byte`: If the user sets the option byte `CKDIVMD to 1`, then `configTIMER_PRESCALE = 4`. Otherwise, if `CKDIVMD is set to 0`, then `configTIMER_PRESCALE = 2`. + +(1) This is applicable for F1KH-D8 with SMP only. + +(2) This is optional and applicable for SMP only. + +## Other Relevant Information + +- **Documentation:** + - Refer to the official [FreeRTOS documentation](https://www.freertos.org/Documentation/RTOS_book.html) for detailed information on configuring and using FreeRTOS. + - Consult the [RH850 F1K group user manual hardware manual](https://www.renesas.com/us/en/document/mah/rh850f1k-group-users-manual-hardware?r=1170166) for specific details about the microcontroller. + - For more information about Renesas RH850/F1K and F1Kx, please visit [this website](https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rh850-automotive-mcus) + - The CC-RH compiler can be downloaded [here](https://www.renesas.com/us/en/software-tool/c-compiler-package-rh850-family#downloads) + +- **Support:** + - If you encounter any issues or have questions about this port, please open an issue in this repository or contact the maintainer. + +- **Contributing:** + - Contributions to improve this port are welcome. Please fork the repository, make your changes, and submit a pull request. \ No newline at end of file diff --git a/portable/CCRH/F1Kx/port.c b/portable/CCRH/F1Kx/port.c new file mode 100644 index 000000000..3a43ff418 --- /dev/null +++ b/portable/CCRH/F1Kx/port.c @@ -0,0 +1,732 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* This port uses xTaskGetCurrentTaskHandle to get TCB stack, it is required to + * enable this API. */ +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle != 1 ) && ( configNUMBER_OF_CORES == 1 ) ) + #error INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 in single core. +#endif + +/*********************************************************** +* Macro definitions +***********************************************************/ + +/* Hardware specific macros */ +#define portPSW_REGISTER_ID ( 5 ) +#define portFPSR_REGISTER_ID ( 6 ) + +/* PSW.EBV and PSW.CUx bits are kept as current status */ +#define portINITIAL_PSW_MASK ( 0x000f8000 ) +#define portCURRENT_PSW_VALUE ( portSTSR( portPSW_REGISTER_ID ) ) +#define portCURRENT_SR_ZERO_VALUE ( ( StackType_t ) 0x00000000 ) +#define portCURRENT_FPSR_VALUE ( portSTSR( portFPSR_REGISTER_ID ) ) + +/* Mask for FPU configuration bits (FN, PEM, RM, FS) */ +#define portINITIAL_FPSR_MASK ( 0x00ae0000 ) +#define portPSW_ID_MASK ( 0x00000020 ) + +/* Define necessary hardware IO for OSTM timer. OSTM0 is used by default as + * it is common for almost device variants. If it conflicts with application, + * the application shall implement another timer.*/ +#define portOSTM_EIC_ADDR ( 0xFFFFB0A8 ) +#define portOSTM0CMP_ADDR ( 0xFFD70000 ) +#define portOSTM0CTL_ADDR ( 0xFFD70020 ) +#define portOSTM0TS_ADDR ( 0xFFD70014 ) + +#if ( configNUMBER_OF_CORES > 1 ) + +/* IPIR base address, the peripheral is used for Inter-Processor communication + * Hardware supports 4 channels which is offset by 0x0, 0x4, 0x8, 0xC bytes from + * base address. By default, channel 0 is selected. */ + #ifdef configIPIR_CHANNEL + #define portIPIR_BASE_ADDR ( ( 0xFFFEEC80 ) + ( configIPIR_CHANNEL << 2 ) ) + #else + #define portIPIR_BASE_ADDR ( 0xFFFEEC80 ) + #endif + +/* Address used for exclusive control for variable shared between PEs + * (common resources), each CPU cores have independent access path to + * this address. By default, G0MEV0 register is selected*/ + #ifdef configEXCLUSIVE_ADDRESS + #define portMEV_BASE_ADDR configEXCLUSIVE_ADDRESS + #else + #define portMEV_BASE_ADDR ( 0xFFFEEC00 ) + #endif +#endif /* if ( configNUMBER_OF_CORES > 1 ) */ + +/* Macros required to set up the initial stack. */ +#define portSTACK_INITIAL_VALUE_R1 ( ( StackType_t ) 0x01010101 ) +#define portSTACK_INITIAL_VALUE_R2 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x02 ) +#define portSTACK_INITIAL_VALUE_R3 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x03 ) +#define portSTACK_INITIAL_VALUE_R4 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x04 ) +#define portSTACK_INITIAL_VALUE_R5 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x05 ) +#define portSTACK_INITIAL_VALUE_R6 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x06 ) +#define portSTACK_INITIAL_VALUE_R7 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x07 ) +#define portSTACK_INITIAL_VALUE_R8 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x08 ) +#define portSTACK_INITIAL_VALUE_R9 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x09 ) +#define portSTACK_INITIAL_VALUE_R10 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x10 ) +#define portSTACK_INITIAL_VALUE_R11 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x11 ) +#define portSTACK_INITIAL_VALUE_R12 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x12 ) +#define portSTACK_INITIAL_VALUE_R13 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x13 ) +#define portSTACK_INITIAL_VALUE_R14 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x14 ) +#define portSTACK_INITIAL_VALUE_R15 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x15 ) +#define portSTACK_INITIAL_VALUE_R16 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x16 ) +#define portSTACK_INITIAL_VALUE_R17 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x17 ) +#define portSTACK_INITIAL_VALUE_R18 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x18 ) +#define portSTACK_INITIAL_VALUE_R19 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x19 ) +#define portSTACK_INITIAL_VALUE_R20 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x20 ) +#define portSTACK_INITIAL_VALUE_R21 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x21 ) +#define portSTACK_INITIAL_VALUE_R22 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x22 ) +#define portSTACK_INITIAL_VALUE_R23 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x23 ) +#define portSTACK_INITIAL_VALUE_R24 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x24 ) +#define portSTACK_INITIAL_VALUE_R25 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x25 ) +#define portSTACK_INITIAL_VALUE_R26 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x26 ) +#define portSTACK_INITIAL_VALUE_R27 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x27 ) +#define portSTACK_INITIAL_VALUE_R28 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x28 ) +#define portSTACK_INITIAL_VALUE_R29 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x29 ) +#define portSTACK_INITIAL_VALUE_R30 ( ( StackType_t ) portSTACK_INITIAL_VALUE_R1 * 0x30 ) + +/*********************************************************** +* Typedef definitions +***********************************************************/ + +/* OSTM Count Start Trigger Register (OSTMnTS) */ +#define portOSTM_COUNTER_START ( 0x01U ) /* Starts the counter */ + +/* OSTM Count Stop Trigger Register (OSTMnTT) */ +#define portOSTM_COUNTER_STOP ( 0x01U ) /* Stops the counter */ + +/* OSTM Control Register (OSTMnCTL) */ +#define portOSTM_MODE_INTERVAL_TIMER ( 0x00U ) +#define portOSTM_MODE_FREE_RUNNING ( 0x02U ) + +/* Disables or Enable the interrupts when counting starts */ +#define portOSTM_START_INTERRUPT_DISABLE ( 0x00U ) +#define portOSTM_START_INTERRUPT_ENABLE ( 0x01U ) + +/* Interrupt vector method select (TBxxx) */ +#define portINT_DIRECT_VECTOR ( 0x0U ) +#define portINT_TABLE_VECTOR ( 0x1U ) + +/* Interrupt mask (MKxxx) */ +#define portINT_PROCESSING_ENABLED ( 0x0U ) +#define portINT_PROCESSING_DISABLED ( 0x1U ) + +/* Specify 16 interrupt priority levels */ +#define portINT_PRIORITY_HIGHEST ( 0x0000U ) /* Level 0 (highest) */ +#define portINT_PRIORITY_LEVEL1 ( 0x0001U ) /* Level 1 */ +#define portINT_PRIORITY_LEVEL2 ( 0x0002U ) /* Level 2 */ +#define portINT_PRIORITY_LEVEL3 ( 0x0003U ) /* Level 3 */ +#define portINT_PRIORITY_LEVEL4 ( 0x0004U ) /* Level 4 */ +#define portINT_PRIORITY_LEVEL5 ( 0x0005U ) /* Level 5 */ +#define portINT_PRIORITY_LEVEL6 ( 0x0006U ) /* Level 6 */ +#define portINT_PRIORITY_LEVEL7 ( 0x0007U ) /* Level 7 */ +#define portINT_PRIORITY_LEVEL8 ( 0x0008U ) /* Level 8 */ +#define portINT_PRIORITY_LEVEL9 ( 0x0009U ) /* Level 9 */ +#define portINT_PRIORITY_LEVEL10 ( 0x000AU ) /* Level 10 */ +#define portINT_PRIORITY_LEVEL11 ( 0x000BU ) /* Level 11 */ +#define portINT_PRIORITY_LEVEL12 ( 0x000CU ) /* Level 12 */ +#define portINT_PRIORITY_LEVEL13 ( 0x000DU ) /* Level 13 */ +#define portINT_PRIORITY_LEVEL14 ( 0x000EU ) /* Level 14 */ +#define portINT_PRIORITY_LOWEST ( 0x000FU ) /* Level 15 (lowest) */ + +/* Macros indicating status of scheduler request */ +#define PORT_SCHEDULER_NOREQUEST 0UL +#define PORT_SCHEDULER_TASKSWITCH 1UL /* Do not modify */ +#define PORT_SCHEDULER_STARTFIRSTTASK 2UL /* Do not modify */ + +#ifndef configSETUP_TICK_INTERRUPT + +/* The user has not provided their own tick interrupt configuration so use + * the definition in this file (which uses the interval timer). */ + #define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt() +#endif /* configSETUP_TICK_INTERRUPT */ + +#if ( !defined( configMAX_INT_NESTING ) || ( configMAX_INT_NESTING == 0 ) ) + +/* Set the default value for depth of nested interrupt. In theory, the + * microcontroller have mechanism to limit number of nested level of interrupt + * by priority (maximum 16 levels). However, the large stack memory should be + * prepared for each task to save resource in interrupt handler. Therefore, it + * is necessary to limit depth of nesting interrupt to optimize memory usage. + * In addition, the execution time of interrupt handler should be very short + * (typically not exceed 20us), this constraint does not impact to system. + */ + #define configMAX_INT_NESTING 2UL +#endif + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/* + * Sets up the periodic ISR used for the RTOS tick using the OSTM. + * The application writer can define configSETUP_TICK_INTERRUPT() (in + * FreeRTOSConfig.h) such that their own tick interrupt configuration is used + * in place of prvSetupTimerInterrupt(). + */ +static void prvSetupTimerInterrupt( void ); + +#if ( configNUMBER_OF_CORES > 1 ) + +/* + * Functions implement spin-lock between cores by atomic accesses to Exclusive + * Control Register (G0MEVm). There are separated access path between CPU cores, + * but they should wait if access to same register + */ + static void prvExclusiveLock( BaseType_t xFromIsr ); + static void prvExclusiveRelease( BaseType_t xFromIsr ); + +#endif + +/* + * Function to start the first task executing + */ +extern void vPortStartFirstTask( void ); + +/* Scheduler request on each cores which are starting first task and switching + * context */ +volatile BaseType_t xPortScheduleStatus[ configNUMBER_OF_CORES ] = { 0 }; + +/* Counts the interrupt nesting depth. A context switch is only performed if + * the nesting depth is 0. In addition, the interrupt shares same stack + * allocated for each tasks. With supporting nesting interrupt, the stack + * may be overflowed. + * It is necessary to control maximum stack depth. + */ +volatile UBaseType_t uxInterruptNesting[ configNUMBER_OF_CORES ] = { 0 }; +volatile const UBaseType_t uxPortMaxInterruptDepth = configMAX_INT_NESTING; + +/* Count number of nested locks by same cores. The lock is completely released + * only if this count is decreased to 0, the lock is separated for task + * and isr */ +UBaseType_t uxLockNesting[ configNUMBER_OF_CORES ][ 2 ] = { 0 }; + +#if ( configNUMBER_OF_CORES > 1 ) + +/* Pointer to exclusive access memory */ + volatile BaseType_t * pxPortExclusiveReg = ( volatile BaseType_t * ) ( portMEV_BASE_ADDR ); +#endif + +/* Interrupt handler for OSTM timer which handling tick increment and resulting + * to switch context. */ +void vPortTickISR( void ); + +#if ( configNUMBER_OF_CORES > 1 ) + +/* Yield specific cores by send inter-processor interrupt */ + void vPortYieldCore( uint32_t xCoreID ); + +/* + * Inter-processor interrupt handler. The interrupt is triggered by + * portYIELD_CORE(). + */ + void vPortIPIHander( void ); + +/* These functions below implement recursive spinlock for exclusive access among + * cores. The core will wait until lock will be available, whilst the core which + * already had lock can acquire lock without waiting. This function could be + * call from task and interrupt context, the critical section is called + * as in ISR */ + void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr ); + void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr ); + +#endif /* (configNUMBER_OF_CORES > 1) */ + +/*-----------------------------------------------------------*/ + +/* + * These below functions implement interrupt mask from interrupt. They are not + * called in nesting, it is protected by FreeRTOS kernel. + */ +portLONG xPortSetInterruptMask( void ) +{ + portLONG ulPSWValue = portSTSR( portPSW_REGISTER_ID ); + + portDISABLE_INTERRUPTS(); + + /* It returns current value of Program Status Word register */ + return ulPSWValue; +} + +/*-----------------------------------------------------------*/ + +void vPortClearInterruptMask( portLONG uxSavedInterruptStatus ) +{ + portLONG ulPSWValue = portSTSR( portPSW_REGISTER_ID ); + + /* Interrupt Disable status is indicates by bit#5 of PSW + * (1: Interrupt is disabled; 0: Interrupt is enabled) */ + + /* Revert to the status before interrupt mask. */ + ulPSWValue &= ( ~( portPSW_ID_MASK ) ); + ulPSWValue |= ( portPSW_ID_MASK & uxSavedInterruptStatus ); + portLDSR( portPSW_REGISTER_ID, ulPSWValue ); +} + +/*-----------------------------------------------------------*/ + +/* + * Using CC-RH intrinsic function to get HTCFG0 (regID, selID) = (0,2) + * Core ID is indicates by bit HTCFG0.PEID located at bit 18 to 16 + * Bit 31 to 19 are read only and always be read as 0. HTCFG0.PEID is 1 and 2 + * corresponding to core 0 (PE1) and core 1 (PE2). It is adjusted to 0 and 1. + */ +BaseType_t xPortGET_CORE_ID( void ) +{ + #if ( configNUMBER_OF_CORES > 1 ) + return ( portSTSR_CCRH( 0, 2 ) >> 16 ) - 1; + #else + + /* In single core, xPortGET_CORE_ID is used in this port only. + * The dummy core ID could be controlled inside this port. */ + return 0; + #endif +} + +/*-----------------------------------------------------------*/ + +/* + * This port supports both multi-cores and single-core, whilst TCB stack + * variables are different which are respectively pxCurrentTCB (single-core) + * and pxCurrentTCBs[] (multiple-cores). This function is defined to obtains + * TCBs of current cores. Also, the C function could switch to corresponding + * pointer by pre-compile conditions. + */ +void * pvPortGetCurrentTCB( void ) +{ + void * pvCurrentTCB = ( void * ) xTaskGetCurrentTaskHandle(); + + configASSERT( pvCurrentTCB != NULL ); + + return pvCurrentTCB; +} + +/*-----------------------------------------------------------*/ + +/* + * This function checks if a context switch is required and, if so, updates + * the scheduler status for the core on which the function is called. The + * scheduler status is set to indicate that a task switch should occur. + */ +void vPortSetSwitch( BaseType_t xSwitchRequired ) +{ + if( xSwitchRequired != pdFALSE ) + { + xPortScheduleStatus[ xPortGET_CORE_ID() ] = PORT_SCHEDULER_TASKSWITCH; + } +} + +/*-----------------------------------------------------------*/ + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in the + * order that the port expects to find them. + * + * @param[in] pxTopOfStack Pointer to top of this task's stack + * @param[in] pxCode Task function, stored as initial PC for the task + * @param[in] pvParameters Parameters for task + */ +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters ) +{ + /* Simulate the stack frame as it would be created by + * a context switch interrupt. */ + *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* R31 (LP) */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R5; /* R5 (TP) */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R7; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R8; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R9; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R10; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R11; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R12; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R13; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R14; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R15; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R16; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R17; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R18; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R19; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R20; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R21; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R22; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R23; /* R23 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R24; /* R24 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R25; /* R25 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R26; /* R26 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R27; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R28; /* R28 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R29; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R30; /* R30 (EP) */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R1; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portSTACK_INITIAL_VALUE_R2; /* R2 */ + + pxTopOfStack--; + + /* Keep System pre-configuration (HV, CUx, EBV) as current setting in + * PSW register */ + *pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* EIPSW */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* EIPC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* EIIC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) ( portCURRENT_PSW_VALUE & portINITIAL_PSW_MASK ); /* CTPSW */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* CTPC */ + +/* __FPU is defined by CCRH compiler if FPU is enabled */ + #if ( configENABLE_FPU == 1 ) + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) ( portCURRENT_FPSR_VALUE & portINITIAL_FPSR_MASK ); /* FPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portCURRENT_SR_ZERO_VALUE; /* FPEPC */ + #endif /* (configENABLE_FPU == 1) */ + + return pxTopOfStack; +} + +/*-----------------------------------------------------------*/ + +/* + * Configures the tick frequency and starts the first task. + */ +BaseType_t xPortStartScheduler( void ) +{ + #if ( configNUMBER_OF_CORES > 1 ) + BaseType_t xCurrentCore = xPortGET_CORE_ID(); + #endif + + /* Prevent interrupt by timer interrupt during starting first task. + * The interrupt shall be enabled automatically by being restored from + * task stack */ + portDISABLE_INTERRUPTS(); + + /* Setup the tick interrupt */ + configSETUP_TICK_INTERRUPT(); + + #if ( configNUMBER_OF_CORES > 1 ) + /* Start scheduler on other cores */ + for( uint16_t xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ ) + { + if( xCoreID != xCurrentCore ) + { + /* Send yielding request to other cores with flag to start + * first task. TaskContextSwitch is not executed */ + xPortScheduleStatus[ xCoreID ] = PORT_SCHEDULER_STARTFIRSTTASK; + vPortYieldCore( xCoreID ); + } + else + { + /* Nothing to do. The first task is started in this call by + * below vPortStartFirstTask() */ + xPortScheduleStatus[ xCoreID ] = PORT_SCHEDULER_NOREQUEST; + } + } + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ + + /* Start first task in primary core */ + vPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! */ + prvTaskExitError(); + + /* To prevent compiler warnings in the case that the application writer + * overrides this functionality by defining configTASK_RETURN_ADDRESS. + * Call vTaskSwitchContext() so link time optimization does not remove + * the symbol. */ + vTaskSwitchContext( + #if ( configNUMBER_OF_CORES > 1 ) + xCurrentCore + #endif + ); + + return pdFALSE; +} + +/*-----------------------------------------------------------*/ + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). + * + * Artificially force an assert() to be triggered if configASSERT() is + * defined, then stop here so application writers can catch the error. */ + + /* This statement will always fail, triggering the assert */ + configASSERT( pdFALSE ); + + /* + * The following statement may be unreachable because configASSERT(pdFALSE) + * always triggers an assertion failure, which typically halts program + * execution. + * The warning may be reported to indicate to indicate that the compiler + * detects the subsequent code will not be executed. + * The warning is acceptable to ensure program is halt regardless of + * configASSERT(pdFALSE) implementation + */ + portDISABLE_INTERRUPTS(); + + for( ; ; ) + { + /* Infinite loop to ensure the function does not return. */ + } +} + +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( pdFALSE ); +} + +/*-----------------------------------------------------------*/ + +#if ( configNUMBER_OF_CORES > 1 ) + + void vPortYieldCore( uint32_t xCoreID ) + { + /* Check if we need to yield on a different core */ + if( xCoreID != xPortGET_CORE_ID() ) + { + volatile uint32_t * pulIPIRReg; + + /* Determine the IPI register based on the target core ID */ + pulIPIRReg = ( volatile uint32_t * ) ( portIPIR_BASE_ADDR ); + + /*Inter-processor interrupt generates an interrupt request by + * writing 1 to applicable bits of target cores. The interrupt + * should be enabled by application in corresponding cores + * including PSW.ID (EI instruction) and interrupt control setting + * for ICIPIRn channel (interrupt mask, vector method) + */ + *pulIPIRReg = ( 1 << xCoreID ); + } + else + { + /* Yielding current core */ + vPortYield(); + } + } + +/*-----------------------------------------------------------*/ + +/* + * Handler for inter-processor interrupt in second cores. The interrupt is + * triggered by portYIELD_CORE(). vTaskSwitchContext() is invoked to + * switch tasks + */ + void vPortIPIHander( void ) + { + BaseType_t xCurrentCore = xPortGET_CORE_ID(); + + /* 1st execution starts 1st task, TaskSwitchContext is not executed */ + if( PORT_SCHEDULER_STARTFIRSTTASK != xPortScheduleStatus[ xCurrentCore ] ) + { + xPortScheduleStatus[ xCurrentCore ] = PORT_SCHEDULER_TASKSWITCH; + } + } + +/*-----------------------------------------------------------*/ + +#endif /* (configNUMBER_OF_CORES > 1) */ + +void vPortTickISR( void ) +{ + /* In case of multicores with SMP, xTaskIncrementTick is required to + * called in critical section to avoid conflict resource as this function + * could be called by xTaskResumeAll() from any cores. */ + #if ( configNUMBER_OF_CORES > 1 ) + BaseType_t xSavedInterruptStatus; + + xSavedInterruptStatus = portENTER_CRITICAL_FROM_ISR(); + #endif + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + xPortScheduleStatus[ xPortGET_CORE_ID() ] = PORT_SCHEDULER_TASKSWITCH; + } + } + #if ( configNUMBER_OF_CORES > 1 ) + portEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + #endif +} + +/*-----------------------------------------------------------*/ + +static void prvSetupTimerInterrupt( void ) +{ + volatile uint32_t * pulOSTMIntReg; + + /* Interrupt configuration for OSTM Timer + * By default, the second lowest priority is set for timer interrupt to + * avoid blocking other interrupt. Normally, user could set the lowest + * priority for non-critical event. It try to keep timer on time. + * In addition, direct vector table is used by default. + */ + pulOSTMIntReg = ( volatile uint32_t * ) portOSTM_EIC_ADDR; + *pulOSTMIntReg = ( portINT_PROCESSING_ENABLED | portINT_DIRECT_VECTOR | portINT_PRIORITY_LEVEL14 ); + + /* Set OSTM0 control setting */ + *( ( volatile uint32_t * ) portOSTM0CTL_ADDR ) = + ( portOSTM_MODE_INTERVAL_TIMER | portOSTM_START_INTERRUPT_DISABLE ); + *( ( volatile uint32_t * ) portOSTM0CMP_ADDR ) = + ( ( configCPU_CLOCK_HZ / configTIMER_PRESCALE ) / configTICK_RATE_HZ ) - 1; + + /* Enable OSTM0 operation */ + *( ( volatile uint32_t * ) portOSTM0TS_ADDR ) = portOSTM_COUNTER_START; +} + +/*-----------------------------------------------------------*/ + +#if ( configNUMBER_OF_CORES > 1 ) + +/* + * These functions implement spin-lock mechanism among cores using hardware + * exclusive control with atomic access by CLR1 and SET1 instruction. + * Nesting calls to these APIs are possible. + */ + #pragma inline_asm prvExclusiveLock + static void prvExclusiveLock( BaseType_t xBitPosition ) + { + /* No problem with r19, CCRH does not required to restore same value + * before and after function call. */ + mov # _pxPortExclusiveReg, r19 + ld.w 0[ r19 ], r19 + +prvExclusiveLock_Lock: + + /* r6 is xBitPosition */ + set1 r6, [ r19 ] + bz prvExclusiveLock_Lock_success + snooze + br prvExclusiveLock_Lock + +prvExclusiveLock_Lock_success: + } + +/*-----------------------------------------------------------*/ + + #pragma inline_asm prvExclusiveRelease + static void prvExclusiveRelease( BaseType_t xBitPosition ) + { + mov # _pxPortExclusiveReg, r19 + ld.w 0[ r19 ], r19 + + /* r6 is xBitPosition */ + clr1 r6, [ r19 ] + } + +/*-----------------------------------------------------------*/ + void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr ) + { + BaseType_t xSavedInterruptStatus; + BaseType_t xBitPosition = ( xFromIsr == pdTRUE ); + + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + + if( uxLockNesting[ xCoreID ][ xBitPosition ] == 0 ) + { + prvExclusiveLock( xBitPosition ); + } + + uxLockNesting[ xCoreID ][ xBitPosition ]++; + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); + } + + void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr ) + { + BaseType_t xSavedInterruptStatus; + BaseType_t xBitPosition = ( xFromIsr == pdTRUE ); + + xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + + /* Sync memory */ + portSYNCM(); + + /* Error check whether vPortRecursiveLockRelease() is not called in + * pair with vPortRecursiveLockAcquire() */ + configASSERT( ( uxLockNesting[ xCoreID ][ xBitPosition ] > 0 ) ); + uxLockNesting[ xCoreID ][ xBitPosition ]--; + + if( uxLockNesting[ xCoreID ][ xBitPosition ] == 0 ) + { + prvExclusiveRelease( xBitPosition ); + } + + portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); + } + +/*-----------------------------------------------------------*/ + +#endif /* (configNUMBER_OF_CORES > 1) */ diff --git a/portable/CCRH/F1Kx/portasm.s b/portable/CCRH/F1Kx/portasm.s new file mode 100644 index 000000000..ff8e7ee31 --- /dev/null +++ b/portable/CCRH/F1Kx/portasm.s @@ -0,0 +1,331 @@ +;/* +; * FreeRTOS Kernel +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * +; * SPDX-License-Identifier: MIT +; * +; * Permission is hereby granted, free of charge, to any person obtaining a copy of +; * this software and associated documentation files (the "Software"), to deal in +; * the Software without restriction, including without limitation the rights to +; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +; * the Software, and to permit persons to whom the Software is furnished to do so, +; * subject to the following conditions: +; * +; * The above copyright notice and this permission notice shall be included in all +; * copies or substantial portions of the Software. +; * +; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +; * +; * https://www.FreeRTOS.org +; * https://github.com/FreeRTOS +; * +; */ + +;------------------------------------------------------------------------------ +; Extern symbols +;------------------------------------------------------------------------------ +.extern _uxInterruptNesting +.extern _uxPortMaxInterruptDepth +.extern _xPortScheduleStatus +.extern _vTaskSwitchContext +.extern _pvPortGetCurrentTCB +.extern _vCommonISRHandler +.extern _xPortGET_CORE_ID + +.public _vIrq_Handler +.public _vPortStartFirstTask +.public _vPortYield +.public _vTRAP0_Handler +;------------------------------------------------------------------------------ +; Macro definitions +;------------------------------------------------------------------------------ +EIPC .set 0 +EIPSW .set 1 +PSW .set 5 +FPSR .set 6 +FPEPC .set 7 +EIIC .set 13 +CTPC .set 16 +CTPSW .set 17 +EIIC_MSK .set 0x00000FFF +FPU_MSK .set 0x00010000 +;------------------------------------------------------------------------------ +; portSAVE_CONTEXT +; Context saving +;------------------------------------------------------------------------------ +portSAVE_CONTEXT .macro + prepare lp, 0 + + ; Save general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC into stack. + pushsp r5, r30 + $nowarning + pushsp r1, r2 + $warning + + stsr EIPSW, r15 + stsr EIPC, r16 + stsr EIIC, r17 + stsr CTPSW, r18 + stsr CTPC, r19 + pushsp r15, r19 + + ; Save FPU registers to stack if FPU is enabled + mov FPU_MSK, r19 + tst r15, r19 + + ; Jump over next 3 instructions: stsr (4 bytes)*2 + pushsp (4 bytes) + bz 12 + stsr FPSR, r18 + stsr FPEPC, r19 + pushsp r18, r19 + + ; Save EIPSW register to stack + ; Due to the syntax of the pushsp instruction, using r14 as dummy value + pushsp r14, r15 + + ; Get current TCB, the return value is stored in r10 (CCRH compiler) + jarl _pvPortGetCurrentTCB, lp + st.w sp, 0[r10] + +.endm + +;------------------------------------------------------------------------------ +; portRESTORE_CONTEXT +; Context restoring +;------------------------------------------------------------------------------ +portRESTORE_CONTEXT .macro + ; Current TCB is returned by r10 (CCRH compiler) + jarl _pvPortGetCurrentTCB, lp + ld.w 0[r10], sp ; Restore the stack pointer from the TCB + + ; Restore FPU registers if FPU is enabled + mov FPU_MSK, r19 + ; Restore EIPSW register to check FPU + ; Due to the syntax of the popsp instruction, using r14 as dummy value + popsp r14, r15 + tst r15, r19 + ; Jump over next 3 instructions: stsr (4 bytes)*2 + popsp (4 bytes) + bz 12 + popsp r18, r19 + ldsr r19, FPEPC + ldsr r18, FPSR + + ;Restore general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC + popsp r15, r19 + ldsr r19, CTPC + ldsr r18, CTPSW + ldsr r17, EIIC + ldsr r16, EIPC + ldsr r15, EIPSW + + $nowarning + popsp r1, r2 + $warning + popsp r5, r30 + + dispose 0, lp +.endm + +;------------------------------------------------------------------------------ +; Save used registers +;------------------------------------------------------------------------------ +SAVE_REGISTER .macro + ; Save general-purpose registers and EIPSW, EIPC, EIIC, CTPSW, CTPC into stack. + ; Callee-Save registers (r20 to r30) are not used in interrupt handler and + ; guaranteed no change after function call. So, don't need to save register + ; to optimize the used stack memory. + pushsp r5, r19 + $nowarning + pushsp r1, r2 + $warning + + stsr EIPSW, r19 + stsr EIPC, r18 + stsr EIIC, r17 + mov lp, r16 + mov ep, r15 + stsr CTPSW, r14 + stsr CTPC, r13 + pushsp r13, r18 + + mov FPU_MSK, r16 + tst r16, r19 + bz 8 + stsr FPSR, r17 + stsr FPEPC, r18 + + pushsp r17, r19 + +.endm +;------------------------------------------------------------------------------ +; Restore used registers +;------------------------------------------------------------------------------ +RESTORE_REGISTER .macro + + mov FPU_MSK, r15 + popsp r17, r19 + tst r19, r15 + bz 8 + ldsr r18, FPEPC + ldsr r17, FPSR + + popsp r13, r18 + ldsr r13, CTPC + ldsr r14, CTPSW + mov r15, ep + mov r16, lp + ldsr r17, EIIC + ldsr r18, EIPC + ldsr r19, EIPSW + + $nowarning + popsp r1, r2 + $warning + popsp r5, r19 +.endm + +;------------------------------------------------------------------------------ +; Start the first task. +;------------------------------------------------------------------------------ +_vPortStartFirstTask: + portRESTORE_CONTEXT + eiret + +;------------------------------------------------------------------------------ +; _vPortYield +;------------------------------------------------------------------------------ +_vPortYield: + trap 0 + jmp [lp] ; Return to caller function + +;------------------------------------------------------------------------------ +; PortYield handler. This is installed as the TRAP exception handler. +;------------------------------------------------------------------------------ +_vTRAP0_Handler: + ;Save the context of the current task. + portSAVE_CONTEXT + + ; The use case that portYield() is called from interrupt context as nested interrupt. + ; Context switch should be executed at the most outer of interrupt tree. + ; In that case, set xPortScheduleStatus to flag context switch in interrupt handler. + jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler) + mov r10, r11 + shl 2, r11 + mov #_uxInterruptNesting, r19 + add r11, r19 + ld.w 0[r19], r18 + cmp r0, r18 + be _vTRAP0_Handler_ContextSwitch + + mov #_xPortScheduleStatus, r19 + add r11, r19 + + ; Set xPortScheduleStatus[coreID]=PORT_SCHEDULER_TASKSWITCH + mov 1, r17 + st.w r17, 0[r19] + br _vTRAP0_Handler_Exit + +_vTRAP0_Handler_ContextSwitch: + ; Pass coreID (r10) as parameter by r6 (CCRH compiler) in SMP support. + mov r10, r6 + ; Call the scheduler to select the next task. + ; vPortYeild may be called to current core again at the end of vTaskSwitchContext. + ; This may case nested interrupt, however, it is not necessary to set + ; uxInterruptNesting (currently 0) for nested trap0 exception. The user interrupt + ; (EI level interrupt) is not accepted inside of trap0 exception. + jarl _vTaskSwitchContext, lp + +_vTRAP0_Handler_Exit: + ; Restore the context of the next task to run. + portRESTORE_CONTEXT + eiret + +;------------------------------------------------------------------------------ +; _Irq_Handler +; Handler interrupt service routine (ISR). +;------------------------------------------------------------------------------ +_vIrq_Handler: + ; Save used registers. + SAVE_REGISTER + + ; Get core ID by HTCFG0, thread configuration register. + ; Then, increase nesting count for current core. + jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler) + shl 2, r10 + mov r10, r17 + + mov #_uxInterruptNesting, r19 + add r17, r19 + ld.w 0[r19], r18 + addi 0x1, r18, r16 + st.w r16, 0[r19] + + pushsp r17, r19 + + ;Call the interrupt handler. + stsr EIIC, r6 + andi EIIC_MSK, r6, r6 + + ; Do not enable interrupt for nesting. Stackover flow may occurs if the + ; depth of nesting interrupt is exceeded. + mov #_uxPortMaxInterruptDepth, r19 + ld.w 0[r19], r15 + cmp r15, r16 + bge 4 ; Jump over ei instruction + ei + jarl _vCommonISRHandler, lp + di + synce + + popsp r17, r19 + st.w r18, 0[r19] ; Restore the old nesting count. + + ; A context switch if no nesting interrupt. + cmp 0x0, r18 + bne _vIrq_Handler_NotSwitchContext + + ; Check if context switch is requested. + mov #_xPortScheduleStatus, r19 + add r17, r19 + ld.w 0[r19], r18 + cmp r0, r18 + bne _vIrq_Handler_SwitchContext + +_vIrq_Handler_NotSwitchContext: + ; No context switch. Restore used registers + RESTORE_REGISTER + eiret + +;This sequence is executed for primary core only to switch context +_vIrq_Handler_SwitchContext: + ; Clear the context switch pending flag. + st.w r0, 0[r19] + + add -1, r18 + bnz _vIrq_Handler_StartFirstTask + ; Restore used registers before saving the context to the task stack. + RESTORE_REGISTER + portSAVE_CONTEXT + + ; Get Core ID and pass to vTaskSwitchContext as parameter (CCRH compiler) + ; The parameter is unused in single core, no problem with this redudant setting + jarl _xPortGET_CORE_ID, lp ; return value is contained in r10 (CCRH compiler) + mov r10, r6 + + ; vPortYeild may be called to current core again at the end of vTaskSwitchContext. + ; This may case nested interrupt, however, it is not necessary to set + ; uxInterruptNesting (currently 0) for trap0 exception. The user interrupt + ; (EI level interrupt) is not accepted inside of trap0 exception. + jarl _vTaskSwitchContext, lp ; + portRESTORE_CONTEXT + eiret + +_vIrq_Handler_StartFirstTask: + RESTORE_REGISTER + jr _vPortStartFirstTask + diff --git a/portable/CCRH/F1Kx/portmacro.h b/portable/CCRH/F1Kx/portmacro.h new file mode 100644 index 000000000..a665ad23d --- /dev/null +++ b/portable/CCRH/F1Kx/portmacro.h @@ -0,0 +1,193 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTMACRO_H + #define PORTMACRO_H + + #ifdef __cplusplus + extern "C" + { + #endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions - These are a bit legacy and not really used now, other + * than portSTACK_TYPE and portBASE_TYPE. */ + #define portCHAR char + #define portFLOAT float + #define portDOUBLE double + #define portLONG long + #define portSHORT short + #define portSTACK_TYPE uint32_t + #define portBASE_TYPE long + + typedef portSTACK_TYPE StackType_t; + typedef long BaseType_t; + typedef unsigned long UBaseType_t; + +/* Defines the maximum time when using a wait command in a task */ + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. + #endif + +/*-----------------------------------------------------------*/ + +/* Architecture specifics */ + + #define portSTSR( reg ) __stsr( ( reg ) ) + #define portLDSR( reg, val ) __ldsr( ( reg ), ( val ) ) + #define portSTSR_CCRH( reg, sel ) __stsr_rh( ( reg ), ( sel ) ) + #define portSYNCM() __syncm() + +/* Determine the descending of the stack from high address to address */ + #define portSTACK_GROWTH ( -1 ) + +/* Determine the time (in milliseconds) corresponding to each tick */ + #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + +/* It is a multiple of 4 (the two lower-order bits of the address = 0), + * otherwise it will cause MAE (Misaligned Exception) according to the manual */ + #define portBYTE_ALIGNMENT ( 4 ) + +/* Interrupt control macros. */ + + #define portENABLE_INTERRUPTS() __EI() /* Macro to enable all maskable interrupts. */ + #define portDISABLE_INTERRUPTS() __DI() /* Macro to disable all maskable interrupts. */ + #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/* SMP build which means configNUM_CORES is relevant */ + #define portSUPPORT_SMP 1 + + #define portMAX_CORE_COUNT 2 + #ifndef configNUMBER_OF_CORES + #define configNUMBER_OF_CORES 1 + #endif + +/*-----------------------------------------------------------*/ +/* Scheduler utilities */ + +/* Called at the end of an ISR that can cause a context switch */ + extern void vPortSetSwitch( BaseType_t xSwitchRequired ); + + #define portEND_SWITCHING_ISR( x ) vPortSetSwitch( x ) + + #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) + +/* Use to transfer control from one task to perform other tasks of + * higher priority */ + extern void vPortYield( void ); + + #define portYIELD() vPortYield() + #if ( configNUMBER_OF_CORES > 1 ) + +/* Return the core ID on which the code is running. */ + extern BaseType_t xPortGET_CORE_ID(); + + #define portGET_CORE_ID() xPortGET_CORE_ID() + #define coreid xPortGET_CORE_ID() + +/* Request the core ID x to yield. */ + extern void vPortYieldCore( uint32_t coreID ); + + #define portYIELD_CORE( x ) vPortYieldCore( x ) + + #define portENTER_CRITICAL_FROM_ISR() vTaskEnterCriticalFromISR() + #define portEXIT_CRITICAL_FROM_ISR( x ) vTaskExitCriticalFromISR( x ) + + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ + + #if ( configNUMBER_OF_CORES == 1 ) + #define portGET_ISR_LOCK( xCoreID ) + #define portRELEASE_ISR_LOCK( xCoreID ) + #define portGET_TASK_LOCK( xCoreID ) + #define portRELEASE_TASK_LOCK( xCoreID ) + #else + extern void vPortRecursiveLockAcquire( BaseType_t xCoreID, BaseType_t xFromIsr ); + extern void vPortRecursiveLockRelease( BaseType_t xCoreID, BaseType_t xFromIsr ); + + #define portGET_ISR_LOCK( xCoreID ) vPortRecursiveLockAcquire( ( xCoreID ), pdTRUE ) + #define portRELEASE_ISR_LOCK( xCoreID ) vPortRecursiveLockRelease( ( xCoreID ), pdTRUE ) + #define portGET_TASK_LOCK( xCoreID ) vPortRecursiveLockAcquire( ( xCoreID ), pdFALSE ) + #define portRELEASE_TASK_LOCK( xCoreID ) vPortRecursiveLockRelease( ( xCoreID ), pdFALSE ) + #endif /* if ( configNUMBER_OF_CORES == 1 ) */ + +/*-----------------------------------------------------------*/ +/* Critical section management. */ + +/* The critical nesting functions defined within tasks.c */ + + extern void vTaskEnterCritical( void ); + extern void vTaskExitCritical( void ); + +/* Macro to mark the start of a critical code region */ + #define portENTER_CRITICAL() vTaskEnterCritical() + +/* Macro to mark the end of a critical code region */ + #define portEXIT_CRITICAL() vTaskExitCritical() + +/*-----------------------------------------------------------*/ +/* Macros to set and clear the interrupt mask. */ + portLONG xPortSetInterruptMask(); + void vPortClearInterruptMask( portLONG ); + + #define portSET_INTERRUPT_MASK() xPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK( x ) vPortClearInterruptMask( ( x ) ) + #define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( ( x ) ) + +/*-----------------------------------------------------------*/ +/* Task function macros as described on the FreeRTOS.org WEB site. */ + + #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) + #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + +/*-----------------------------------------------------------*/ + + #ifdef __cplusplus +} + #endif +#endif /* PORTMACRO_H */ diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c index e8b0f0d74..8373c14c0 100644 --- a/portable/CCS/ARM_CM3/port.c +++ b/portable/CCS/ARM_CM3/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -669,7 +669,7 @@ void vPortSetupTimerInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/CCS/ARM_CM3/portasm.asm b/portable/CCS/ARM_CM3/portasm.asm index 2773c6ca2..483a66b49 100644 --- a/portable/CCS/ARM_CM3/portasm.asm +++ b/portable/CCS/ARM_CM3/portasm.asm @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/CCS/ARM_CM3/portmacro.h b/portable/CCS/ARM_CM3/portmacro.h index 29d9bc033..42498555f 100644 --- a/portable/CCS/ARM_CM3/portmacro.h +++ b/portable/CCS/ARM_CM3/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -170,7 +170,7 @@ #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ - #ifdef configASSERT + #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c index c3a9b0f4b..1ad05077d 100644 --- a/portable/CCS/ARM_CM4F/port.c +++ b/portable/CCS/ARM_CM4F/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -694,7 +694,7 @@ void vPortSetupTimerInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/CCS/ARM_CM4F/portasm.asm b/portable/CCS/ARM_CM4F/portasm.asm index eb75533bd..81d0a71c2 100644 --- a/portable/CCS/ARM_CM4F/portasm.asm +++ b/portable/CCS/ARM_CM4F/portasm.asm @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/CCS/ARM_CM4F/portmacro.h b/portable/CCS/ARM_CM4F/portmacro.h index f4405ab1b..faefd124c 100644 --- a/portable/CCS/ARM_CM4F/portmacro.h +++ b/portable/CCS/ARM_CM4F/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -164,7 +164,7 @@ #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ - #ifdef configASSERT + #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/CCS/ARM_Cortex-R4/port.c b/portable/CCS/ARM_Cortex-R4/port.c index 6c63a5a71..853248f40 100644 --- a/portable/CCS/ARM_Cortex-R4/port.c +++ b/portable/CCS/ARM_Cortex-R4/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CCS/ARM_Cortex-R4/portASM.asm b/portable/CCS/ARM_Cortex-R4/portASM.asm index 927df85d4..f20af2941 100644 --- a/portable/CCS/ARM_Cortex-R4/portASM.asm +++ b/portable/CCS/ARM_Cortex-R4/portASM.asm @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/CCS/ARM_Cortex-R4/portmacro.h b/portable/CCS/ARM_Cortex-R4/portmacro.h index 07c1827cb..644f13a3c 100644 --- a/portable/CCS/ARM_Cortex-R4/portmacro.h +++ b/portable/CCS/ARM_Cortex-R4/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CCS/MSP430X/data_model.h b/portable/CCS/MSP430X/data_model.h index 186caa65d..b199175c0 100644 --- a/portable/CCS/MSP430X/data_model.h +++ b/portable/CCS/MSP430X/data_model.h @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/CCS/MSP430X/port.c b/portable/CCS/MSP430X/port.c index c691b5d9f..2097a2931 100644 --- a/portable/CCS/MSP430X/port.c +++ b/portable/CCS/MSP430X/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -26,6 +26,9 @@ * */ +/* Hardware includes. */ +#include "msp430.h" + /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" diff --git a/portable/CCS/MSP430X/portext.asm b/portable/CCS/MSP430X/portext.asm index 9fe306e94..dbbcec0aa 100644 --- a/portable/CCS/MSP430X/portext.asm +++ b/portable/CCS/MSP430X/portext.asm @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/CCS/MSP430X/portmacro.h b/portable/CCS/MSP430X/portmacro.h index 064b0503a..c00c5a902 100644 --- a/portable/CCS/MSP430X/portmacro.h +++ b/portable/CCS/MSP430X/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -39,9 +39,6 @@ *----------------------------------------------------------- */ -/* Hardware includes. */ -#include "msp430.h" - /* Type definitions. */ #define portCHAR char #define portFLOAT float @@ -75,8 +72,8 @@ typedef unsigned short UBaseType_t; /*-----------------------------------------------------------*/ /* Interrupt control macros. */ -#define portDISABLE_INTERRUPTS() _disable_interrupt(); _nop() -#define portENABLE_INTERRUPTS() _enable_interrupt(); _nop() +#define portDISABLE_INTERRUPTS() __asm volatile ( " DINT\n" " NOP" ) +#define portENABLE_INTERRUPTS() __asm volatile ( " NOP\n" " EINT\n" " NOP" ) /*-----------------------------------------------------------*/ /* Critical section control macros. */ @@ -126,7 +123,7 @@ extern void vPortYield( void ); #define portBYTE_ALIGNMENT 2 #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portNOP() __no_operation() +#define portNOP() __asm volatile ( " NOP" ) /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt index b84b3018b..a634965f4 100644 --- a/portable/CMakeLists.txt +++ b/portable/CMakeLists.txt @@ -15,7 +15,7 @@ endif() # FreeRTOS internal cmake file. Do not use it in user top-level project -add_library(freertos_kernel_port STATIC +add_library(freertos_kernel_port OBJECT # TEMPLATE Port $<$: template/port.c> @@ -68,20 +68,21 @@ add_library(freertos_kernel_port STATIC # ARMv8-A ports for GCC $<$: - GCC/Arm_AARCH64/port.c - GCC/Arm_AARCH64/portASM.S> + GCC/ARM_AARCH64/port.c + GCC/ARM_AARCH64/portASM.S> $<$: - GCC/Arm_AARCH64_SRE/port.c - GCC/Arm_AARCH64_SRE/portASM.S> + GCC/ARM_AARCH64_SRE/port.c + GCC/ARM_AARCH64_SRE/portASM.S> # ARMv6-M port for GCC $<$: - GCC/ARM_CM0/port.c> + GCC/ARM_CM0/port.c + GCC/ARM_CM0/portasm.c + GCC/ARM_CM0/mpu_wrappers_v2_asm.c> # ARMv6-M / Cortex-M0 Raspberry PI RP2040 port for GCC $<$: - ThirdParty/GCC/RP2040/idle_task_static_memory.c ThirdParty/GCC/RP2040/port.c> # ARMv7-M ports for GCC @@ -89,11 +90,13 @@ add_library(freertos_kernel_port STATIC GCC/ARM_CM3/port.c> $<$: - GCC/ARM_CM3_MPU/port.c> + GCC/ARM_CM3_MPU/port.c + GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c> # ARMv7E-M ports for GCC $<$: - GCC/ARM_CM4_MPU/port.c> + GCC/ARM_CM4_MPU/port.c + GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM4F/port.c> @@ -104,7 +107,8 @@ add_library(freertos_kernel_port STATIC # ARMv8-M ports for GCC $<$: GCC/ARM_CM23/non_secure/port.c - GCC/ARM_CM23/non_secure/portasm.c> + GCC/ARM_CM23/non_secure/portasm.c + GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM23/secure/secure_context_port.c @@ -114,11 +118,13 @@ add_library(freertos_kernel_port STATIC $<$: GCC/ARM_CM23_NTZ/non_secure/port.c - GCC/ARM_CM23_NTZ/non_secure/portasm.c> + GCC/ARM_CM23_NTZ/non_secure/portasm.c + GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM33/non_secure/port.c - GCC/ARM_CM33/non_secure/portasm.c> + GCC/ARM_CM33/non_secure/portasm.c + GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM33/secure/secure_context_port.c @@ -128,16 +134,19 @@ add_library(freertos_kernel_port STATIC $<$: GCC/ARM_CM33_NTZ/non_secure/port.c - GCC/ARM_CM33_NTZ/non_secure/portasm.c> + GCC/ARM_CM33_NTZ/non_secure/portasm.c + GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM33_NTZ/non_secure/port.c GCC/ARM_CM33_NTZ/non_secure/portasm.c + GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> $<$: GCC/ARM_CM35P/non_secure/port.c - GCC/ARM_CM35P/non_secure/portasm.c> + GCC/ARM_CM35P/non_secure/portasm.c + GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM35P/secure/secure_context_port.c @@ -147,12 +156,14 @@ add_library(freertos_kernel_port STATIC $<$: GCC/ARM_CM35P_NTZ/non_secure/port.c - GCC/ARM_CM35P_NTZ/non_secure/portasm.c> + GCC/ARM_CM35P_NTZ/non_secure/portasm.c + GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c> # ARMv8.1-M ports for GCC $<$: GCC/ARM_CM55/non_secure/port.c - GCC/ARM_CM55/non_secure/portasm.c> + GCC/ARM_CM55/non_secure/portasm.c + GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM55/secure/secure_context_port.c @@ -162,16 +173,19 @@ add_library(freertos_kernel_port STATIC $<$: GCC/ARM_CM55_NTZ/non_secure/port.c - GCC/ARM_CM55_NTZ/non_secure/portasm.c> + GCC/ARM_CM55_NTZ/non_secure/portasm.c + GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM55_NTZ/non_secure/port.c GCC/ARM_CM55_NTZ/non_secure/portasm.c + GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> $<$: GCC/ARM_CM85/non_secure/port.c - GCC/ARM_CM85/non_secure/portasm.c> + GCC/ARM_CM85/non_secure/portasm.c + GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM85/secure/secure_context_port.c @@ -181,11 +195,13 @@ add_library(freertos_kernel_port STATIC $<$: GCC/ARM_CM85_NTZ/non_secure/port.c - GCC/ARM_CM85_NTZ/non_secure/portasm.c> + GCC/ARM_CM85_NTZ/non_secure/portasm.c + GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c> $<$: GCC/ARM_CM85_NTZ/non_secure/port.c GCC/ARM_CM85_NTZ/non_secure/portasm.c + GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> # ARMv7-R ports for GCC @@ -193,10 +209,20 @@ add_library(freertos_kernel_port STATIC GCC/ARM_CR5/port.c GCC/ARM_CR5/portASM.S> + $<$: + GCC/ARM_CRx_MPU/port.c + GCC/ARM_CRx_MPU/portASM.S + GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S> + $<$: GCC/ARM_CRx_No_GIC/port.c GCC/ARM_CRx_No_GIC/portASM.S> + # ARMv8-R ports for GCC + $<$: + GCC/ARM_CR82/port.c + GCC/ARM_CR82/portASM.S> + # ARMv4T ARM7TDMI ports for GCC $<$: GCC/ARM7_AT91FR40008/port.c @@ -392,7 +418,8 @@ add_library(freertos_kernel_port STATIC $<$: IAR/ARM_CM4F_MPU/port.c - IAR/ARM_CM4F_MPU/portasm.s> + IAR/ARM_CM4F_MPU/portasm.s + IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S> $<$: IAR/ARM_CM7/r0p1/port.c @@ -401,7 +428,8 @@ add_library(freertos_kernel_port STATIC # ARMv8-M Ports for IAR EWARM $<$: IAR/ARM_CM23/non_secure/port.c - IAR/ARM_CM23/non_secure/portasm.s> + IAR/ARM_CM23/non_secure/portasm.s + IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S> $<$: IAR/ARM_CM23/secure/secure_context_port_asm.s @@ -411,11 +439,13 @@ add_library(freertos_kernel_port STATIC $<$: IAR/ARM_CM23_NTZ/non_secure/port.c - IAR/ARM_CM23_NTZ/non_secure/portasm.s> + IAR/ARM_CM23_NTZ/non_secure/portasm.s + IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S> $<$: IAR/ARM_CM33/non_secure/port.c - IAR/ARM_CM33/non_secure/portasm.s> + IAR/ARM_CM33/non_secure/portasm.s + IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S> $<$: IAR/ARM_CM33/secure/secure_context_port_asm.s @@ -425,11 +455,19 @@ add_library(freertos_kernel_port STATIC $<$: IAR/ARM_CM33_NTZ/non_secure/port.c - IAR/ARM_CM33_NTZ/non_secure/portasm.s> + IAR/ARM_CM33_NTZ/non_secure/portasm.s + IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S> + + $<$: + IAR/ARM_CM33_NTZ/non_secure/port.c + IAR/ARM_CM33_NTZ/non_secure/portasm.s + IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S + ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> $<$: IAR/ARM_CM35P/non_secure/port.c - IAR/ARM_CM35P/non_secure/portasm.s> + IAR/ARM_CM35P/non_secure/portasm.s + IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S> $<$: IAR/ARM_CM35P/secure/secure_context_port_asm.s @@ -439,12 +477,14 @@ add_library(freertos_kernel_port STATIC $<$: IAR/ARM_CM35P_NTZ/non_secure/port.c - IAR/ARM_CM35P_NTZ/non_secure/portasm.s> + IAR/ARM_CM35P_NTZ/non_secure/portasm.s + IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S> # ARMv8.1-M ports for IAR EWARM $<$: IAR/ARM_CM55/non_secure/port.c - IAR/ARM_CM55/non_secure/portasm.s> + IAR/ARM_CM55/non_secure/portasm.s + IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S> $<$: IAR/ARM_CM55/secure/secure_context_port_asm.s @@ -454,11 +494,19 @@ add_library(freertos_kernel_port STATIC $<$: IAR/ARM_CM55_NTZ/non_secure/port.c - IAR/ARM_CM55_NTZ/non_secure/portasm.s> + IAR/ARM_CM55_NTZ/non_secure/portasm.s + IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S> + + $<$: + IAR/ARM_CM55_NTZ/non_secure/port.c + IAR/ARM_CM55_NTZ/non_secure/portasm.s + IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S + ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> $<$: IAR/ARM_CM85/non_secure/port.c - IAR/ARM_CM85/non_secure/portasm.s> + IAR/ARM_CM85/non_secure/portasm.s + IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S> $<$: IAR/ARM_CM85/secure/secure_context_port_asm.s @@ -468,7 +516,14 @@ add_library(freertos_kernel_port STATIC $<$: IAR/ARM_CM85_NTZ/non_secure/port.c - IAR/ARM_CM85_NTZ/non_secure/portasm.s> + IAR/ARM_CM85_NTZ/non_secure/portasm.s + IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S> + + $<$: + IAR/ARM_CM85_NTZ/non_secure/port.c + IAR/ARM_CM85_NTZ/non_secure/portasm.s + IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S + ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> # ARMv7-R Ports for IAR EWARM $<$: @@ -660,7 +715,8 @@ add_library(freertos_kernel_port STATIC # ARMv7E-M ports for ARM RVDS / armcc $<$: - RVDS/ARM_CM4_MPU/port.c> + RVDS/ARM_CM4_MPU/port.c + RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c> $<$: RVDS/ARM_CM4F/port.c> @@ -718,16 +774,120 @@ add_library(freertos_kernel_port STATIC 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 FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR - FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE" + FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE" OR + FREERTOS_PORT MATCHES "IAR_ARM_CM(33|55|85)_TFM" ) - target_sources(freertos_kernel_port PRIVATE Common/mpu_wrappers.c) + target_sources(freertos_kernel_port PRIVATE + Common/mpu_wrappers.c + Common/mpu_wrappers_v2.c + ) endif() -target_include_directories(freertos_kernel_port PUBLIC +if (DEFINED FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG ) + + if(${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + message(FATAL_ERROR "ARMv8.1-M PACBTI support in the kernel is not yet enabled for GNU toolchain due to known issues.") + endif() + + if(FREERTOS_PORT MATCHES ".*ARM_CM85") + if(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_STANDARD") + target_compile_options(freertos_kernel_port PUBLIC $<$:-mbranch-protection=standard>) + target_compile_options(freertos_kernel_port PUBLIC $<$:$<$:--branch_protection=bti+pac-ret>>) + target_compile_definitions(freertos_config + INTERFACE + configENABLE_PAC=1 + configENABLE_BTI=1 + ) + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(freertos_kernel_port + PUBLIC + -mbranch-protection=bti+pac-ret+leaf + ) + target_compile_definitions(freertos_config + INTERFACE + configENABLE_PAC=1 + configENABLE_BTI=1 + ) + elseif(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + message(FATAL_ERROR "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI PACBTI option is not supported on IAR Compiler.") + endif() + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET") + target_compile_options(freertos_kernel_port PUBLIC $<$:-mbranch-protection=pac-ret>) + target_compile_options(freertos_kernel_port PUBLIC $<$:$<$:--branch_protection=pac-ret>>) + target_compile_definitions(freertos_config + INTERFACE + configENABLE_PAC=1 + ) + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(freertos_kernel_port + PUBLIC + -mbranch-protection=pac-ret+leaf + ) + target_compile_definitions(freertos_config + INTERFACE + configENABLE_PAC=1 + ) + elseif(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + message(FATAL_ERROR "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF PACBTI option is not supported on IAR Compiler.") + endif() + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_BTI") + target_compile_options(freertos_kernel_port PUBLIC $<$:-mbranch-protection=bti>) + target_compile_options(freertos_kernel_port PUBLIC $<$:$<$:--branch_protection=bti>>) + target_compile_definitions(freertos_config + INTERFACE + configENABLE_BTI=1 + ) + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_NONE") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(freertos_kernel_port + PUBLIC + -mbranch-protection=none + ) + endif() + target_compile_definitions(freertos_config + INTERFACE + configENABLE_PAC=0 + configENABLE_BTI=0 + ) + else() + message(FATAL_ERROR "Invalid FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG configuration, the supported configurations are + ARM_V_8_1_M_PACBTI_CONFIG_STANDARD, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF, + ARM_V_8_1_M_PACBTI_CONFIG_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_NONE + ") + endif() + if(NOT FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_NONE") + # The reason why `--library_security=pacbti-m` link option is defined for both `freertos_kernel_port`, and + # `freertos_kernel` targets even though `freertos_kernel_port` gets linked to `freertos_kernel` is that the + # `freertos_kernel_port` is an object library where its linker options don't propagate to the targets that + # link against it. + target_link_options(freertos_kernel_port + PUBLIC + --library_security=pacbti-m + ) + target_link_options(freertos_kernel + PUBLIC + --library_security=pacbti-m + ) + endif() + else() + message(FATAL_ERROR "FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option is currently only supported on ARM Cortex-M85 FreeRTOS port.") + endif() +endif() + +add_library(freertos_kernel_port_headers INTERFACE) + +target_include_directories(freertos_kernel_port_headers INTERFACE # TEMPLATE Port $<$:${CMAKE_CURRENT_LIST_DIR}/template> @@ -761,8 +921,8 @@ target_include_directories(freertos_kernel_port PUBLIC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CA9> # ARMv8-A ports for GCC - $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/Arm_AARCH64> - $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/Arm_AARCH64_SRE> + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_AARCH64> + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_AARCH64_SRE> # ARMv6-M port for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM0> @@ -806,8 +966,12 @@ target_include_directories(freertos_kernel_port PUBLIC # ARMv7-R ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5> + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_MPU> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC> + # ARMv8-R ports for GCC + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR82> + # ARMv4T ARM7TDMI ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91FR40008> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91SAM7S> @@ -918,6 +1082,7 @@ target_include_directories(freertos_kernel_port PUBLIC $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM35P/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM35P/secure> @@ -927,10 +1092,12 @@ target_include_directories(freertos_kernel_port PUBLIC $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure> # ARMv7-R Ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CRx_No_GIC> @@ -1057,6 +1224,11 @@ target_include_directories(freertos_kernel_port PUBLIC $<$:${CMAKE_CURRENT_LIST_DIR}/WizC/PIC18> ) +target_link_libraries(freertos_kernel_port_headers + INTERFACE + $<$:hardware_sync> +) + if(FREERTOS_PORT STREQUAL GCC_POSIX) find_package(Threads REQUIRED) endif() @@ -1065,9 +1237,10 @@ target_link_libraries(freertos_kernel_port PUBLIC $<$:pico_base_headers> $<$:idf::esp32> + freertos_kernel_port_headers PRIVATE freertos_kernel_include $<$:Threads::Threads> - "$<$:hardware_clocks;hardware_exception>" + "$<$:hardware_clocks;hardware_exception;pico_multicore>" $<$:winmm> # Windows library which implements timers ) diff --git a/portable/CodeWarrior/ColdFire_V1/port.c b/portable/CodeWarrior/ColdFire_V1/port.c index d9831384e..520c62ac5 100644 --- a/portable/CodeWarrior/ColdFire_V1/port.c +++ b/portable/CodeWarrior/ColdFire_V1/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CodeWarrior/ColdFire_V1/portasm.S b/portable/CodeWarrior/ColdFire_V1/portasm.S index 75f55f037..1f00348af 100644 --- a/portable/CodeWarrior/ColdFire_V1/portasm.S +++ b/portable/CodeWarrior/ColdFire_V1/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CodeWarrior/ColdFire_V1/portmacro.h b/portable/CodeWarrior/ColdFire_V1/portmacro.h index a98093d72..2f224d30b 100644 --- a/portable/CodeWarrior/ColdFire_V1/portmacro.h +++ b/portable/CodeWarrior/ColdFire_V1/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CodeWarrior/ColdFire_V2/port.c b/portable/CodeWarrior/ColdFire_V2/port.c index 5bca650fe..64b2d078b 100644 --- a/portable/CodeWarrior/ColdFire_V2/port.c +++ b/portable/CodeWarrior/ColdFire_V2/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CodeWarrior/ColdFire_V2/portasm.S b/portable/CodeWarrior/ColdFire_V2/portasm.S index bdffce5e8..66f429259 100644 --- a/portable/CodeWarrior/ColdFire_V2/portasm.S +++ b/portable/CodeWarrior/ColdFire_V2/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CodeWarrior/ColdFire_V2/portmacro.h b/portable/CodeWarrior/ColdFire_V2/portmacro.h index a59dff9dd..55b38ae3a 100644 --- a/portable/CodeWarrior/ColdFire_V2/portmacro.h +++ b/portable/CodeWarrior/ColdFire_V2/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CodeWarrior/HCS12/port.c b/portable/CodeWarrior/HCS12/port.c index e4876125a..2d564cd66 100644 --- a/portable/CodeWarrior/HCS12/port.c +++ b/portable/CodeWarrior/HCS12/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/CodeWarrior/HCS12/portmacro.h b/portable/CodeWarrior/HCS12/portmacro.h index d0d0a140e..8e6eb1057 100644 --- a/portable/CodeWarrior/HCS12/portmacro.h +++ b/portable/CodeWarrior/HCS12/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Common/mpu_wrappers.c b/portable/Common/mpu_wrappers.c index 969bf2d3e..5bc4181e2 100644 --- a/portable/Common/mpu_wrappers.c +++ b/portable/Common/mpu_wrappers.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -57,7 +57,7 @@ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, - uint16_t usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ @@ -72,7 +72,7 @@ uxPriority = uxPriority & ~( portPRIVILEGE_BIT ); portMEMORY_BARRIER(); - xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + xReturn = xTaskCreate( pvTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); @@ -80,7 +80,7 @@ } else { - xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + xReturn = xTaskCreate( pvTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask ); } return xReturn; @@ -91,7 +91,7 @@ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -107,7 +107,7 @@ uxPriority = uxPriority & ~( portPRIVILEGE_BIT ); portMEMORY_BARRIER(); - xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + xReturn = xTaskCreateStatic( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); @@ -115,7 +115,7 @@ } else { - xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + xReturn = xTaskCreateStatic( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); } return xReturn; @@ -508,14 +508,15 @@ /*-----------------------------------------------------------*/ #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - void MPU_vTaskList( char * pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + void MPU_vTaskListTasks( char * pcWriteBuffer, + size_t uxBufferLength ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); - vTaskList( pcWriteBuffer ); + vTaskListTasks( pcWriteBuffer, uxBufferLength ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); @@ -523,21 +524,22 @@ } else { - vTaskList( pcWriteBuffer ); + vTaskListTasks( pcWriteBuffer, uxBufferLength ); } } #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + void MPU_vTaskGetRunTimeStatistics( char * pcWriteBuffer, + size_t uxBufferLength ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); - vTaskGetRunTimeStats( pcWriteBuffer ); + vTaskGetRunTimeStatistics( pcWriteBuffer, uxBufferLength ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); @@ -545,7 +547,7 @@ } else { - vTaskGetRunTimeStats( pcWriteBuffer ); + vTaskGetRunTimeStatistics( pcWriteBuffer, uxBufferLength ); } } #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ @@ -834,7 +836,7 @@ #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ /*-----------------------------------------------------------*/ - #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_RECURSIVE_MUTEXES == 1 ) ) TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ { TaskHandle_t xReturn; @@ -856,7 +858,7 @@ return xReturn; } - #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ + #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_RECURSIVE_MUTEXES == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetSchedulerState == 1 ) @@ -1522,6 +1524,34 @@ #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ + #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue ); + } + + return xReturn; + } + #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + #if ( configUSE_QUEUE_SETS == 1 ) QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */ @@ -1797,14 +1827,14 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); - vTimerSetReloadMode( xTimer, uxAutoReload ); + vTimerSetReloadMode( xTimer, xAutoReload ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); @@ -1812,7 +1842,7 @@ } else { - vTimerSetReloadMode( xTimer, uxAutoReload ); + vTimerSetReloadMode( xTimer, xAutoReload ); } } #endif /* if ( configUSE_TIMERS == 1 ) */ @@ -1952,7 +1982,7 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) EventGroupHandle_t MPU_xEventGroupCreate( void ) /* FREERTOS_SYSTEM_CALL */ { EventGroupHandle_t xReturn; @@ -1975,10 +2005,10 @@ return xReturn; } - #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + #endif /* #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) /* FREERTOS_SYSTEM_CALL */ { EventGroupHandle_t xReturn; @@ -2001,387 +2031,417 @@ return xReturn; } - #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + #if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + } + + return xReturn; + } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + } + + return xReturn; + } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + } + + return xReturn; + } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, - const BaseType_t xClearOnExit, - const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ - { - EventBits_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + EventBits_t xReturn; - xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + } + + return xReturn; } - else - { - xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); - } - - return xReturn; - } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ - { - EventBits_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_EVENT_GROUPS == 1 ) + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); - portMEMORY_BARRIER(); + vEventGroupDelete( xEventGroup ); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vEventGroupDelete( xEventGroup ); + } } - else - { - xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); - } - - return xReturn; - } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ - { - EventBits_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + size_t xReturn; - xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); + } + + return xReturn; } - else - { - xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ - { - EventBits_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + size_t xReturn; - xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); + } + + return xReturn; } - else - { - xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* FREERTOS_SYSTEM_CALL */ - { - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + size_t xReturn; - vEventGroupDelete( xEventGroup ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); + } + + return xReturn; } - else - { - vEventGroupDelete( xEventGroup ); - } - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ - { - size_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); - portMEMORY_BARRIER(); + vStreamBufferDelete( xStreamBuffer ); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vStreamBufferDelete( xStreamBuffer ); + } } - else - { - xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ - { - size_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + BaseType_t xReturn; - xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferIsFull( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferIsFull( xStreamBuffer ); + } + + return xReturn; } - else - { - xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ - { - size_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + BaseType_t xReturn; - xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferIsEmpty( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferIsEmpty( xStreamBuffer ); + } + + return xReturn; } - else - { - xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ - { - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + BaseType_t xReturn; - vStreamBufferDelete( xStreamBuffer ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferReset( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferReset( xStreamBuffer ); + } + + return xReturn; } - else - { - vStreamBufferDelete( xStreamBuffer ); - } - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ - { - BaseType_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + size_t xReturn; - xReturn = xStreamBufferIsFull( xStreamBuffer ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); + } + + return xReturn; } - else - { - xReturn = xStreamBufferIsFull( xStreamBuffer ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ - { - BaseType_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + size_t xReturn; - xReturn = xStreamBufferIsEmpty( xStreamBuffer ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); + } + + return xReturn; } - else - { - xReturn = xStreamBufferIsEmpty( xStreamBuffer ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ - { - BaseType_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); + BaseType_t xReturn; - xReturn = xStreamBufferReset( xStreamBuffer ); - portMEMORY_BARRIER(); + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); + xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); + } + + return xReturn; } - else - { - xReturn = xStreamBufferReset( xStreamBuffer ); - } - - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ - { - size_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) - { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); - xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); - portMEMORY_BARRIER(); - - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); - } - else - { - xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); - } - - return xReturn; - } -/*-----------------------------------------------------------*/ - - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ - { - size_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) - { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); - - xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); - portMEMORY_BARRIER(); - - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); - } - else - { - xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); - } - - return xReturn; - } -/*-----------------------------------------------------------*/ - - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ - { - BaseType_t xReturn; - - if( portIS_PRIVILEGED() == pdFALSE ) - { - portRAISE_PRIVILEGE(); - portMEMORY_BARRIER(); - - xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); - portMEMORY_BARRIER(); - - portRESET_PRIVILEGE(); - portMEMORY_BARRIER(); - } - else - { - xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); - } - - return xReturn; - } -/*-----------------------------------------------------------*/ - - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* FREERTOS_SYSTEM_CALL */ { StreamBufferHandle_t xReturn; /** - * Streambuffer application level callback functionality is disabled for MPU + * Stream buffer application level callback functionality is disabled for MPU * enabled ports. */ configASSERT( ( pxSendCompletedCallback == NULL ) && @@ -2397,7 +2457,7 @@ xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, - xIsMessageBuffer, + xStreamBufferType, NULL, NULL ); portMEMORY_BARRIER(); @@ -2409,26 +2469,26 @@ { xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, - xIsMessageBuffer, + xStreamBufferType, NULL, NULL ); } } else { - traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType ); xReturn = NULL; } return xReturn; } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + #endif /* #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, @@ -2437,7 +2497,7 @@ StreamBufferHandle_t xReturn; /** - * Streambuffer application level callback functionality is disabled for MPU + * Stream buffer application level callback functionality is disabled for MPU * enabled ports. */ configASSERT( ( pxSendCompletedCallback == NULL ) && @@ -2453,7 +2513,7 @@ xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, - xIsMessageBuffer, + xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, NULL, @@ -2467,7 +2527,7 @@ { xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, - xIsMessageBuffer, + xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, NULL, @@ -2476,13 +2536,13 @@ } else { - traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType ); xReturn = NULL; } return xReturn; } - #endif /* configSUPPORT_STATIC_ALLOCATION */ + #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) */ /*-----------------------------------------------------------*/ diff --git a/portable/Common/mpu_wrappers_v2.c b/portable/Common/mpu_wrappers_v2.c index 832a7f844..70082b829 100644 --- a/portable/Common/mpu_wrappers_v2.c +++ b/portable/Common/mpu_wrappers_v2.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -92,16 +92,16 @@ /** * @brief Checks whether an external index is valid or not. */ - #define IS_EXTERNAL_INDEX_VALID( lIndex ) \ - ( ( ( lIndex ) >= INDEX_OFFSET ) && \ - ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE + INDEX_OFFSET ) ) ) + #define IS_EXTERNAL_INDEX_VALID( lIndex ) \ + ( ( ( ( lIndex ) >= INDEX_OFFSET ) && \ + ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE + INDEX_OFFSET ) ) ) ? pdTRUE : pdFALSE ) /** * @brief Checks whether an internal index is valid or not. */ - #define IS_INTERNAL_INDEX_VALID( lIndex ) \ - ( ( ( lIndex ) >= 0 ) && \ - ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE ) ) ) + #define IS_INTERNAL_INDEX_VALID( lIndex ) \ + ( ( ( ( lIndex ) >= 0 ) && \ + ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE ) ) ) ? pdTRUE : pdFALSE ) /** * @brief Converts an internal index into external. @@ -197,46 +197,51 @@ /* * Wrappers to keep all the casting in one place. */ - #define MPU_StoreQueueHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) - #define MPU_GetQueueHandleAtIndex( lIndex ) ( QueueHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_StoreQueueHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( ( lIndex ), ( OpaqueObjectHandle_t ) ( xHandle ), NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueHandleAtIndex( lIndex ) ( QueueHandle_t ) MPU_GetHandleAtIndex( ( lIndex ), KERNEL_OBJECT_TYPE_QUEUE ) #if ( configUSE_QUEUE_SETS == 1 ) - #define MPU_StoreQueueSetHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) - #define MPU_GetQueueSetHandleAtIndex( lIndex ) ( QueueSetHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) - #define MPU_StoreQueueSetMemberHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) - #define MPU_GetQueueSetMemberHandleAtIndex( lIndex ) ( QueueSetMemberHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) - #define MPU_GetIndexForQueueSetMemberHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_StoreQueueSetHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( ( lIndex ), ( OpaqueObjectHandle_t ) ( xHandle ), NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueSetHandleAtIndex( lIndex ) ( QueueSetHandle_t ) MPU_GetHandleAtIndex( ( lIndex ), KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_StoreQueueSetMemberHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( ( lIndex ), ( OpaqueObjectHandle_t ) ( xHandle ), NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueSetMemberHandleAtIndex( lIndex ) ( QueueSetMemberHandle_t ) MPU_GetHandleAtIndex( ( lIndex ), KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetIndexForQueueSetMemberHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) ( xHandle ), KERNEL_OBJECT_TYPE_QUEUE ) #endif /* * Wrappers to keep all the casting in one place for Task APIs. */ - #define MPU_StoreTaskHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_TASK ) - #define MPU_GetTaskHandleAtIndex( lIndex ) ( TaskHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_TASK ) - #define MPU_GetIndexForTaskHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_TASK ) + #define MPU_StoreTaskHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( ( lIndex ), ( OpaqueObjectHandle_t ) ( xHandle ), NULL, KERNEL_OBJECT_TYPE_TASK ) + #define MPU_GetTaskHandleAtIndex( lIndex ) ( TaskHandle_t ) MPU_GetHandleAtIndex( ( lIndex ), KERNEL_OBJECT_TYPE_TASK ) + #define MPU_GetIndexForTaskHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) ( xHandle ), KERNEL_OBJECT_TYPE_TASK ) + #if ( configUSE_EVENT_GROUPS == 1 ) /* * Wrappers to keep all the casting in one place for Event Group APIs. */ - #define MPU_StoreEventGroupHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_EVENT_GROUP ) - #define MPU_GetEventGroupHandleAtIndex( lIndex ) ( EventGroupHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_EVENT_GROUP ) - #define MPU_GetIndexForEventGroupHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #define MPU_StoreEventGroupHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( ( lIndex ), ( OpaqueObjectHandle_t ) ( xHandle ), NULL, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #define MPU_GetEventGroupHandleAtIndex( lIndex ) ( EventGroupHandle_t ) MPU_GetHandleAtIndex( ( lIndex ), KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #define MPU_GetIndexForEventGroupHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) ( xHandle ), KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ + + #if ( configUSE_STREAM_BUFFERS == 1 ) /* * Wrappers to keep all the casting in one place for Stream Buffer APIs. */ - #define MPU_StoreStreamBufferHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) - #define MPU_GetStreamBufferHandleAtIndex( lIndex ) ( StreamBufferHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) - #define MPU_GetIndexForStreamBufferHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + #define MPU_StoreStreamBufferHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( ( lIndex ), ( OpaqueObjectHandle_t ) ( xHandle), NULL, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + #define MPU_GetStreamBufferHandleAtIndex( lIndex ) ( StreamBufferHandle_t ) MPU_GetHandleAtIndex( ( lIndex ), KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + #define MPU_GetIndexForStreamBufferHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) ( xHandle ), KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ #if ( configUSE_TIMERS == 1 ) - /* * Wrappers to keep all the casting in one place for Timer APIs. */ - #define MPU_StoreTimerHandleAtIndex( lIndex, xHandle, pxApplicationCallback ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, ( void * ) pxApplicationCallback, KERNEL_OBJECT_TYPE_TIMER ) - #define MPU_GetTimerHandleAtIndex( lIndex ) ( TimerHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_TIMER ) - #define MPU_GetIndexForTimerHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_TIMER ) + #define MPU_StoreTimerHandleAtIndex( lIndex, xHandle, pxApplicationCallback ) MPU_StoreHandleAndDataAtIndex( ( lIndex ), ( OpaqueObjectHandle_t ) ( xHandle ), ( void * ) ( pxApplicationCallback ), KERNEL_OBJECT_TYPE_TIMER ) + #define MPU_GetTimerHandleAtIndex( lIndex ) ( TimerHandle_t ) MPU_GetHandleAtIndex( ( lIndex ), KERNEL_OBJECT_TYPE_TIMER ) + #define MPU_GetIndexForTimerHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) ( xHandle ), KERNEL_OBJECT_TYPE_TIMER ) #endif /* #if ( configUSE_TIMERS == 1 ) */ @@ -245,7 +250,7 @@ /** * @brief Kernel object pool. */ - PRIVILEGED_DATA static KernelObject_t xKernelObjectPool[ configPROTECTED_KERNEL_OBJECT_POOL_SIZE ] = { NULL }; + PRIVILEGED_DATA static KernelObject_t xKernelObjectPool[ configPROTECTED_KERNEL_OBJECT_POOL_SIZE ] = { 0 }; /*-----------------------------------------------------------*/ static int32_t MPU_GetFreeIndexInKernelObjectPool( void ) /* PRIVILEGED_FUNCTION */ @@ -263,13 +268,13 @@ if( xKernelObjectPool[ i ].xInternalObjectHandle == NULL ) { /* Mark this index as not free. */ - xKernelObjectPool[ i ].xInternalObjectHandle = ( OpaqueObjectHandle_t ) ( ~0 ); + xKernelObjectPool[ i ].xInternalObjectHandle = ( OpaqueObjectHandle_t ) ( ~0U ); lFreeIndex = i; break; } } } - xTaskResumeAll(); + ( void ) xTaskResumeAll(); return lFreeIndex; } @@ -1054,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 ); @@ -1167,7 +1172,7 @@ #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ /*-----------------------------------------------------------*/ - #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_RECURSIVE_MUTEXES == 1 ) ) TaskHandle_t MPU_xTaskGetCurrentTaskHandleImpl( void ) PRIVILEGED_FUNCTION; @@ -1192,7 +1197,7 @@ return xExternalTaskHandle; } - #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ + #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_RECURSIVE_MUTEXES == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetSchedulerState == 1 ) @@ -1541,7 +1546,7 @@ BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, - uint16_t usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask ) /* PRIVILEGED_FUNCTION */ @@ -1557,7 +1562,7 @@ /* xTaskCreate() can only be used to create privileged tasks in MPU port. */ if( ( uxPriority & portPRIVILEGE_BIT ) != 0 ) { - xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, &( xInternalTaskHandle ) ); + xReturn = xTaskCreate( pvTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, &( xInternalTaskHandle ) ); if( ( xReturn == pdPASS ) && ( xInternalTaskHandle != NULL ) ) { @@ -1585,7 +1590,7 @@ TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -1599,7 +1604,7 @@ if( lIndex != -1 ) { - xInternalTaskHandle = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + xInternalTaskHandle = xTaskCreateStatic( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); if( xInternalTaskHandle != NULL ) { @@ -2197,7 +2202,7 @@ if( ( !( ( pvItemToQueue == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) && ( !( ( xCopyPosition == queueOVERWRITE ) && ( uxQueueLength != ( UBaseType_t ) 1U ) ) ) #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0U ) ) ) #endif ) { @@ -2312,7 +2317,7 @@ if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0U ) ) ) #endif ) { @@ -2364,7 +2369,7 @@ if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0U ) ) ) #endif ) { @@ -2411,9 +2416,9 @@ { uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); - if( ( uxQueueItemSize == 0 ) + if( ( uxQueueItemSize == 0U ) #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0U ) ) ) #endif ) { @@ -2964,7 +2969,7 @@ QueueHandle_t xInternalQueueHandle = NULL; BaseType_t xReturn = pdFAIL; - lIndex = ( uint32_t ) xQueue; + lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { @@ -3011,6 +3016,39 @@ #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ + #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t MPU_xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue ) /* PRIVILEGED_FUNCTION */ + { + QueueSetHandle_t xInternalQueueSetHandle = NULL; + QueueSetHandle_t xExternalQueueSetHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueSetHandle = xQueueCreateSetStatic( uxEventQueueLength, pucQueueStorage, pxStaticQueue ); + + if( xInternalQueueSetHandle != NULL ) + { + MPU_StoreQueueSetHandleAtIndex( lIndex, xInternalQueueSetHandle ); + xExternalQueueSetHandle = ( QueueSetHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueSetHandle; + } + + #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + #if ( configUSE_QUEUE_SETS == 1 ) BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, @@ -3553,10 +3591,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, - const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; + const BaseType_t xAutoReload ) PRIVILEGED_FUNCTION; void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, - const UBaseType_t uxAutoReload ) /* PRIVILEGED_FUNCTION */ + const BaseType_t xAutoReload ) /* PRIVILEGED_FUNCTION */ { TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; @@ -3574,7 +3612,7 @@ if( xInternalTimerHandle != NULL ) { - vTimerSetReloadMode( xInternalTimerHandle, uxAutoReload ); + vTimerSetReloadMode( xInternalTimerHandle, xAutoReload ); } } } @@ -3728,7 +3766,7 @@ TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /* PRIVILEGED_FUNCTION */ { @@ -3740,7 +3778,7 @@ if( lIndex != -1 ) { - xInternalTimerHandle = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback ); + xInternalTimerHandle = xTimerCreate( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, MPU_TimerCallback ); if( xInternalTimerHandle != NULL ) { @@ -3763,7 +3801,7 @@ TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ) /* PRIVILEGED_FUNCTION */ @@ -3776,7 +3814,7 @@ if( lIndex != -1 ) { - xInternalTimerHandle = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback, pxTimerBuffer ); + xInternalTimerHandle = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, MPU_TimerCallback, pxTimerBuffer ); if( xInternalTimerHandle != NULL ) { @@ -3833,27 +3871,16 @@ BaseType_t xReturn = pdFALSE; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; - BaseType_t xIsHigherPriorityTaskWokenWriteable = pdFALSE; - if( pxHigherPriorityTaskWoken != NULL ) + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xIsHigherPriorityTaskWokenWriteable = xPortIsAuthorizedToAccessBuffer( pxHigherPriorityTaskWoken, - sizeof( BaseType_t ), - tskMPU_WRITE_PERMISSION ); - } + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( ( pxHigherPriorityTaskWoken == NULL ) || ( xIsHigherPriorityTaskWokenWriteable == pdTRUE ) ) - { - lIndex = ( int32_t ) xTimer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + if( xInternalTimerHandle != NULL ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - - if( xInternalTimerHandle != NULL ) - { - xReturn = xTimerGenericCommandFromISR( xInternalTimerHandle, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); - } + xReturn = xTimerGenericCommandFromISR( xInternalTimerHandle, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); } } @@ -3867,53 +3894,99 @@ /* MPU wrappers for event group APIs. */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToWaitFor, - const BaseType_t xClearOnExit, - const BaseType_t xWaitForAllBits, - TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ - { - EventBits_t xReturn = 0; - xEventGroupWaitBitsParams_t xParams; + #if ( configUSE_EVENT_GROUPS == 1 ) - xParams.xEventGroup = xEventGroup; - xParams.uxBitsToWaitFor = uxBitsToWaitFor; - xParams.xClearOnExit = xClearOnExit; - xParams.xWaitForAllBits = xWaitForAllBits; - xParams.xTicksToWait = xTicksToWait; - - xReturn = MPU_xEventGroupWaitBitsEntry( &( xParams ) ); - - return xReturn; - } - - EventBits_t MPU_xEventGroupWaitBitsImpl( const xEventGroupWaitBitsParams_t * pxParams ) PRIVILEGED_FUNCTION; - - EventBits_t MPU_xEventGroupWaitBitsImpl( const xEventGroupWaitBitsParams_t * pxParams ) /* PRIVILEGED_FUNCTION */ - { - EventBits_t xReturn = 0; - EventGroupHandle_t xInternalEventGroupHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; - BaseType_t xAreParamsReadable = pdFALSE; - - if( pxParams != NULL ) + EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ { - xAreParamsReadable = xPortIsAuthorizedToAccessBuffer( pxParams, - sizeof( xEventGroupWaitBitsParams_t ), - tskMPU_READ_PERMISSION ); + EventBits_t xReturn = 0; + xEventGroupWaitBitsParams_t xParams; + + xParams.xEventGroup = xEventGroup; + xParams.uxBitsToWaitFor = uxBitsToWaitFor; + xParams.xClearOnExit = xClearOnExit; + xParams.xWaitForAllBits = xWaitForAllBits; + xParams.xTicksToWait = xTicksToWait; + + xReturn = MPU_xEventGroupWaitBitsEntry( &( xParams ) ); + + return xReturn; } - if( xAreParamsReadable == pdTRUE ) + EventBits_t MPU_xEventGroupWaitBitsImpl( const xEventGroupWaitBitsParams_t * pxParams ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupWaitBitsImpl( const xEventGroupWaitBitsParams_t * pxParams ) /* PRIVILEGED_FUNCTION */ { - if( ( ( pxParams->uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) && - ( pxParams->uxBitsToWaitFor != 0 ) - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( pxParams->xTicksToWait != 0 ) ) ) - #endif - ) + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + BaseType_t xAreParamsReadable = pdFALSE; + + if( pxParams != NULL ) { - lIndex = ( int32_t ) ( pxParams->xEventGroup ); + xAreParamsReadable = xPortIsAuthorizedToAccessBuffer( pxParams, + sizeof( xEventGroupWaitBitsParams_t ), + tskMPU_READ_PERMISSION ); + } + + if( xAreParamsReadable == pdTRUE ) + { + if( ( ( pxParams->uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0U ) && + ( pxParams->uxBitsToWaitFor != 0U ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( pxParams->xTicksToWait != 0U ) ) ) + #endif + ) + { + lIndex = ( int32_t ) ( pxParams->xEventGroup ); + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupWaitBits( xInternalEventGroupHandle, + pxParams->uxBitsToWaitFor, + pxParams->xClearOnExit, + pxParams->xWaitForAllBits, + pxParams->xTicksToWait ); + } + } + } + } + } + + return xReturn; + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_EVENT_GROUPS == 1 ) + + EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + + if( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0U ) + { + lIndex = ( int32_t ) xEventGroup; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { @@ -3925,136 +3998,106 @@ if( xInternalEventGroupHandle != NULL ) { - xReturn = xEventGroupWaitBits( xInternalEventGroupHandle, - pxParams->uxBitsToWaitFor, - pxParams->xClearOnExit, - pxParams->xWaitForAllBits, - pxParams->xTicksToWait ); + xReturn = xEventGroupClearBits( xInternalEventGroupHandle, uxBitsToClear ); } } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */ - { - EventBits_t xReturn = 0; - EventGroupHandle_t xInternalEventGroupHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; - if( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) + EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* PRIVILEGED_FUNCTION */ { - lIndex = ( int32_t ) xEventGroup; + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + if( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0U ) { - xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + lIndex = ( int32_t ) xEventGroup; - if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - xReturn = xEventGroupClearBits( xInternalEventGroupHandle, uxBitsToClear ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSetBits( xInternalEventGroupHandle, uxBitsToSet ); + } } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* PRIVILEGED_FUNCTION */ - { - EventBits_t xReturn = 0; - EventGroupHandle_t xInternalEventGroupHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; - if( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) + EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ { - lIndex = ( int32_t ) xEventGroup; + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + if( ( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0U ) && + ( uxBitsToWaitFor != 0U ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0U ) ) ) + #endif + ) { - xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + lIndex = ( int32_t ) xEventGroup; - if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - xReturn = xEventGroupSetBits( xInternalEventGroupHandle, uxBitsToSet ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSync( xInternalEventGroupHandle, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + } } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; - - EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ - { - EventBits_t xReturn = 0; - EventGroupHandle_t xInternalEventGroupHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; - - if( ( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) && - ( uxBitsToWaitFor != 0 ) - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) - #endif - ) - { - lIndex = ( int32_t ) xEventGroup; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) - { - xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - - if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) - { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - - if( xInternalEventGroupHandle != NULL ) - { - xReturn = xEventGroupSync( xInternalEventGroupHandle, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); - } - } - } - } - - return xReturn; - } -/*-----------------------------------------------------------*/ - - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumberImpl( void * xEventGroup ) PRIVILEGED_FUNCTION; @@ -4085,10 +4128,10 @@ return xReturn; } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumberImpl( void * xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; @@ -4118,7 +4161,7 @@ } } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ /* Privileged only wrappers for Event Group APIs. These are needed so that @@ -4126,7 +4169,7 @@ * with all the APIs. */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) EventGroupHandle_t MPU_xEventGroupCreate( void ) /* PRIVILEGED_FUNCTION */ { @@ -4154,10 +4197,10 @@ return xExternalEventGroupHandle; } - #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + #endif /* #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) /* PRIVILEGED_FUNCTION */ { @@ -4185,30 +4228,34 @@ return xExternalEventGroupHandle; } - #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */ /*-----------------------------------------------------------*/ - void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ - { - EventGroupHandle_t xInternalEventGroupHandle = NULL; - int32_t lIndex; + #if ( configUSE_EVENT_GROUPS == 1 ) - lIndex = ( int32_t ) xEventGroup; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; - if( xInternalEventGroupHandle != NULL ) + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - vEventGroupDelete( xInternalEventGroupHandle ); - MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + vEventGroupDelete( xInternalEventGroupHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } } } - } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, StaticEventGroup_t ** ppxEventGroupBuffer ) /* PRIVILEGED_FUNCTION */ @@ -4232,10 +4279,10 @@ return xReturn; } - #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( ( 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 */ @@ -4259,10 +4306,10 @@ return xReturn; } - #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( ( 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, @@ -4287,309 +4334,345 @@ return xReturn; } - #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ - { - EventBits_t xReturn = 0; - EventGroupHandle_t xInternalEventGroupHandle = NULL; - int32_t lIndex; + #if ( configUSE_EVENT_GROUPS == 1 ) - lIndex = ( int32_t ) xEventGroup; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; - if( xInternalEventGroupHandle != NULL ) + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xReturn = xEventGroupGetBitsFromISR( xInternalEventGroupHandle ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupGetBitsFromISR( xInternalEventGroupHandle ); + } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/ /* MPU wrappers for stream buffer APIs. */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ - { - size_t xReturn = 0; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xIsTxDataBufferReadable = pdFALSE; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; - if( pvTxData != NULL ) + size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ { - xIsTxDataBufferReadable = xPortIsAuthorizedToAccessBuffer( pvTxData, - xDataLengthBytes, - tskMPU_READ_PERMISSION ); + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xIsTxDataBufferReadable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xIsTxDataBufferReadable == pdTRUE ) + if( pvTxData != NULL ) { - lIndex = ( int32_t ) xStreamBuffer; + xIsTxDataBufferReadable = xPortIsAuthorizedToAccessBuffer( pvTxData, + xDataLengthBytes, + tskMPU_READ_PERMISSION ); - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + if( xIsTxDataBufferReadable == pdTRUE ) { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + lIndex = ( int32_t ) xStreamBuffer; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferSend( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, xTicksToWait ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSend( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, xTicksToWait ); + } } } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ - { - size_t xReturn = 0; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xIsRxDataBufferWriteable = pdFALSE; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; - if( pvRxData != NULL ) + size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ { - xIsRxDataBufferWriteable = xPortIsAuthorizedToAccessBuffer( pvRxData, - xBufferLengthBytes, - tskMPU_WRITE_PERMISSION ); + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xIsRxDataBufferWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xIsRxDataBufferWriteable == pdTRUE ) + if( pvRxData != NULL ) { - lIndex = ( int32_t ) xStreamBuffer; + xIsRxDataBufferWriteable = xPortIsAuthorizedToAccessBuffer( pvRxData, + xBufferLengthBytes, + tskMPU_WRITE_PERMISSION ); - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + if( xIsRxDataBufferWriteable == pdTRUE ) { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + lIndex = ( int32_t ) xStreamBuffer; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferReceive( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, xTicksToWait ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceive( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, xTicksToWait ); + } } } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ - { - BaseType_t xReturn = pdFALSE; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferIsFull( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsFull( xInternalStreamBufferHandle ); + } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ - { - BaseType_t xReturn = pdFALSE; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferIsEmpty( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsEmpty( xInternalStreamBufferHandle ); + } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ - { - size_t xReturn = 0; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferSpacesAvailable( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSpacesAvailable( xInternalStreamBufferHandle ); + } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ - { - size_t xReturn = 0; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferBytesAvailable( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferBytesAvailable( xInternalStreamBufferHandle ); + } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* PRIVILEGED_FUNCTION */ - { - BaseType_t xReturn = pdFALSE; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) PRIVILEGED_FUNCTION; - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* PRIVILEGED_FUNCTION */ { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferSetTriggerLevel( xInternalStreamBufferHandle, xTriggerLevel ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSetTriggerLevel( xInternalStreamBufferHandle, xTriggerLevel ); + } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ - { - size_t xReturn = 0; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ { - xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; - if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferNextMessageLengthBytes( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferNextMessageLengthBytes( xInternalStreamBufferHandle ); + } } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ /* Privileged only wrappers for Stream Buffer APIs. These are needed so that @@ -4597,11 +4680,11 @@ * with all the APIs. */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* PRIVILEGED_FUNCTION */ { @@ -4625,7 +4708,7 @@ { xInternalStreamBufferHandle = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, - xIsMessageBuffer, + xStreamBufferType, NULL, NULL ); @@ -4642,21 +4725,21 @@ } else { - traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType ); xExternalStreamBufferHandle = NULL; } return xExternalStreamBufferHandle; } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + #endif /* #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, @@ -4682,7 +4765,7 @@ { xInternalStreamBufferHandle = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, - xIsMessageBuffer, + xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, NULL, @@ -4701,60 +4784,68 @@ } else { - traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType ); xExternalStreamBufferHandle = NULL; } return xExternalStreamBufferHandle; } - #endif /* configSUPPORT_STATIC_ALLOCATION */ + #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) */ /*-----------------------------------------------------------*/ - void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ - { - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; + #if ( configUSE_STREAM_BUFFERS == 1 ) - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; - if( xInternalStreamBufferHandle != NULL ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - vStreamBufferDelete( xInternalStreamBufferHandle ); - } + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - } - } -/*-----------------------------------------------------------*/ + if( xInternalStreamBufferHandle != NULL ) + { + vStreamBufferDelete( xInternalStreamBufferHandle ); + } - BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ - { - BaseType_t xReturn = pdFALSE; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; - - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) - { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - - if( xInternalStreamBufferHandle != NULL ) - { - xReturn = xStreamBufferReset( xInternalStreamBufferHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); } } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( configUSE_STREAM_BUFFERS == 1 ) + + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReset( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers, uint8_t * ppucStreamBufferStorageArea, @@ -4779,9 +4870,11 @@ return xReturn; } - #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_STREAM_BUFFERS == 1 ) ) */ /*-----------------------------------------------------------*/ + #if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, @@ -4805,8 +4898,12 @@ return xReturn; } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ + #if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, @@ -4830,52 +4927,89 @@ return xReturn; } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, - BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ - { - BaseType_t xReturn = pdFALSE; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; + #if ( configUSE_STREAM_BUFFERS == 1 ) - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; - if( xInternalStreamBufferHandle != NULL ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xReturn = xStreamBufferSendCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSendCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, - BaseType_t * pxHigherPriorityTaskWoken ) /*PRIVILEGED_FUNCTION */ - { - BaseType_t xReturn = pdFALSE; - StreamBufferHandle_t xInternalStreamBufferHandle = NULL; - int32_t lIndex; + #if ( configUSE_STREAM_BUFFERS == 1 ) - lIndex = ( int32_t ) xStreamBuffer; - - if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) /*PRIVILEGED_FUNCTION */ { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; - if( xInternalStreamBufferHandle != NULL ) + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xReturn = xStreamBufferReceiveCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceiveCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + } } + + return xReturn; } - return xReturn; - } + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ + +/*-----------------------------------------------------------*/ + + #if ( configUSE_STREAM_BUFFERS == 1 ) + + BaseType_t MPU_xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) /*PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferResetFromISR( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ @@ -4909,7 +5043,11 @@ ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerGenericCommandFromTask. */ #endif - ( UBaseType_t ) MPU_xEventGroupWaitBitsImpl, /* SYSTEM_CALL_xEventGroupWaitBits. */ + #if ( configUSE_EVENT_GROUPS == 1 ) + ( UBaseType_t ) MPU_xEventGroupWaitBitsImpl, /* SYSTEM_CALL_xEventGroupWaitBits. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xEventGroupWaitBits. */ + #endif /* The system calls above this line take 5 parameters. */ @@ -5104,26 +5242,46 @@ ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerGetExpiryTime. */ #endif - ( UBaseType_t ) MPU_xEventGroupClearBitsImpl, /* SYSTEM_CALL_xEventGroupClearBits. */ - ( UBaseType_t ) MPU_xEventGroupSetBitsImpl, /* SYSTEM_CALL_xEventGroupSetBits. */ - ( UBaseType_t ) MPU_xEventGroupSyncImpl, /* SYSTEM_CALL_xEventGroupSync. */ + #if ( configUSE_EVENT_GROUPS == 1 ) + ( UBaseType_t ) MPU_xEventGroupClearBitsImpl, /* SYSTEM_CALL_xEventGroupClearBits. */ + ( UBaseType_t ) MPU_xEventGroupSetBitsImpl, /* SYSTEM_CALL_xEventGroupSetBits. */ + ( UBaseType_t ) MPU_xEventGroupSyncImpl, /* SYSTEM_CALL_xEventGroupSync. */ - #if ( configUSE_TRACE_FACILITY == 1 ) - ( UBaseType_t ) MPU_uxEventGroupGetNumberImpl, /* SYSTEM_CALL_uxEventGroupGetNumber. */ - ( UBaseType_t ) MPU_vEventGroupSetNumberImpl, /* SYSTEM_CALL_vEventGroupSetNumber. */ + #if ( configUSE_TRACE_FACILITY == 1 ) + ( UBaseType_t ) MPU_uxEventGroupGetNumberImpl, /* SYSTEM_CALL_uxEventGroupGetNumber. */ + ( UBaseType_t ) MPU_vEventGroupSetNumberImpl, /* SYSTEM_CALL_vEventGroupSetNumber. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_uxEventGroupGetNumber. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_vEventGroupSetNumber. */ + #endif #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xEventGroupClearBits. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xEventGroupSetBits. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xEventGroupSync. */ ( UBaseType_t ) 0, /* SYSTEM_CALL_uxEventGroupGetNumber. */ ( UBaseType_t ) 0, /* SYSTEM_CALL_vEventGroupSetNumber. */ #endif - ( UBaseType_t ) MPU_xStreamBufferSendImpl, /* SYSTEM_CALL_xStreamBufferSend. */ - ( UBaseType_t ) MPU_xStreamBufferReceiveImpl, /* SYSTEM_CALL_xStreamBufferReceive. */ - ( UBaseType_t ) MPU_xStreamBufferIsFullImpl, /* SYSTEM_CALL_xStreamBufferIsFull. */ - ( UBaseType_t ) MPU_xStreamBufferIsEmptyImpl, /* SYSTEM_CALL_xStreamBufferIsEmpty. */ - ( UBaseType_t ) MPU_xStreamBufferSpacesAvailableImpl, /* SYSTEM_CALL_xStreamBufferSpacesAvailable. */ - ( UBaseType_t ) MPU_xStreamBufferBytesAvailableImpl, /* SYSTEM_CALL_xStreamBufferBytesAvailable. */ - ( UBaseType_t ) MPU_xStreamBufferSetTriggerLevelImpl, /* SYSTEM_CALL_xStreamBufferSetTriggerLevel. */ - ( UBaseType_t ) MPU_xStreamBufferNextMessageLengthBytesImpl /* SYSTEM_CALL_xStreamBufferNextMessageLengthBytes. */ + #if ( configUSE_STREAM_BUFFERS == 1 ) + ( UBaseType_t ) MPU_xStreamBufferSendImpl, /* SYSTEM_CALL_xStreamBufferSend. */ + ( UBaseType_t ) MPU_xStreamBufferReceiveImpl, /* SYSTEM_CALL_xStreamBufferReceive. */ + ( UBaseType_t ) MPU_xStreamBufferIsFullImpl, /* SYSTEM_CALL_xStreamBufferIsFull. */ + ( UBaseType_t ) MPU_xStreamBufferIsEmptyImpl, /* SYSTEM_CALL_xStreamBufferIsEmpty. */ + ( UBaseType_t ) MPU_xStreamBufferSpacesAvailableImpl, /* SYSTEM_CALL_xStreamBufferSpacesAvailable. */ + ( UBaseType_t ) MPU_xStreamBufferBytesAvailableImpl, /* SYSTEM_CALL_xStreamBufferBytesAvailable. */ + ( UBaseType_t ) MPU_xStreamBufferSetTriggerLevelImpl, /* SYSTEM_CALL_xStreamBufferSetTriggerLevel. */ + ( UBaseType_t ) MPU_xStreamBufferNextMessageLengthBytesImpl /* SYSTEM_CALL_xStreamBufferNextMessageLengthBytes. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferSend. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferReceive. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferIsFull. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferIsEmpty. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferSpacesAvailable. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferBytesAvailable. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferSetTriggerLevel. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xStreamBufferNextMessageLengthBytes. */ + #endif + }; /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM7_AT91FR40008/port.c b/portable/GCC/ARM7_AT91FR40008/port.c index 86cc6e0f3..30bbb9f48 100644 --- a/portable/GCC/ARM7_AT91FR40008/port.c +++ b/portable/GCC/ARM7_AT91FR40008/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_AT91FR40008/portISR.c b/portable/GCC/ARM7_AT91FR40008/portISR.c index 9df08b0c9..b4ddcc06d 100644 --- a/portable/GCC/ARM7_AT91FR40008/portISR.c +++ b/portable/GCC/ARM7_AT91FR40008/portISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_AT91FR40008/portmacro.h b/portable/GCC/ARM7_AT91FR40008/portmacro.h index f0975cc3e..4dbadab3f 100644 --- a/portable/GCC/ARM7_AT91FR40008/portmacro.h +++ b/portable/GCC/ARM7_AT91FR40008/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h b/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h index a335e4ad2..e5aa862e0 100644 --- a/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h +++ b/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h b/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h index a680c4861..a148b18a6 100644 --- a/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h +++ b/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ @@ -3125,9 +3125,9 @@ AT91C_MC_RCB EQU( 0x1 << 0 ); -( MC ) Remap Command Bit /* - -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ AT91C_MC_UNDADD EQU( 0x1 << 0 ); --( MC ) Undefined Addess Abort Status +-( MC ) Undefined Address Abort Status AT91C_MC_MISADD EQU( 0x1 << 1 ); --( MC ) Misaligned Addess Abort Status +-( MC ) Misaligned Address Abort Status AT91C_MC_ABTSZ EQU( 0x3 << 8 ); -( MC ) Abort Size Status AT91C_MC_ABTSZ_BYTE EQU( 0x0 << 8 ); @@ -5698,7 +5698,7 @@ AT91C_US_CLKS EQU( 0x3 << 4 ); AT91C_EMAC_SA3H EQU( 0xFFFDC0AC ); -( EMAC ) Specific Address 3 Top, Last 2 bytes AT91C_EMAC_RRE EQU( 0xFFFDC06C ); - -( EMAC ) Receive Ressource Error Register + -( EMAC ) Receive Resource Error Register AT91C_EMAC_STE EQU( 0xFFFDC084 ); -( EMAC ) SQE Test Error Register /* - ========== Register definition for PDC_ADC peripheral ========== */ diff --git a/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h b/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h index 0d9a70884..5de1aee3b 100644 --- a/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h +++ b/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h @@ -210,7 +210,7 @@ /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -222,7 +222,7 @@ /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -234,7 +234,7 @@ /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -246,7 +246,7 @@ /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; diff --git a/portable/GCC/ARM7_AT91SAM7S/port.c b/portable/GCC/ARM7_AT91SAM7S/port.c index f1afce707..6750c45ee 100644 --- a/portable/GCC/ARM7_AT91SAM7S/port.c +++ b/portable/GCC/ARM7_AT91SAM7S/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_AT91SAM7S/portISR.c b/portable/GCC/ARM7_AT91SAM7S/portISR.c index 917c67ddb..9e5ff6c98 100644 --- a/portable/GCC/ARM7_AT91SAM7S/portISR.c +++ b/portable/GCC/ARM7_AT91SAM7S/portISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_AT91SAM7S/portmacro.h b/portable/GCC/ARM7_AT91SAM7S/portmacro.h index 5b78481e3..3f2242fa9 100644 --- a/portable/GCC/ARM7_AT91SAM7S/portmacro.h +++ b/portable/GCC/ARM7_AT91SAM7S/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_LPC2000/port.c b/portable/GCC/ARM7_LPC2000/port.c index 53df1a534..2c8268af5 100644 --- a/portable/GCC/ARM7_LPC2000/port.c +++ b/portable/GCC/ARM7_LPC2000/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_LPC2000/portISR.c b/portable/GCC/ARM7_LPC2000/portISR.c index 704907f9d..4255df713 100644 --- a/portable/GCC/ARM7_LPC2000/portISR.c +++ b/portable/GCC/ARM7_LPC2000/portISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_LPC2000/portmacro.h b/portable/GCC/ARM7_LPC2000/portmacro.h index b96c6fa8b..8e82cc08e 100644 --- a/portable/GCC/ARM7_LPC2000/portmacro.h +++ b/portable/GCC/ARM7_LPC2000/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_LPC23xx/port.c b/portable/GCC/ARM7_LPC23xx/port.c index 4ec34eb3f..8ac1df709 100644 --- a/portable/GCC/ARM7_LPC23xx/port.c +++ b/portable/GCC/ARM7_LPC23xx/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_LPC23xx/portISR.c b/portable/GCC/ARM7_LPC23xx/portISR.c index 4fc549aca..1cf7c7dae 100644 --- a/portable/GCC/ARM7_LPC23xx/portISR.c +++ b/portable/GCC/ARM7_LPC23xx/portISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM7_LPC23xx/portmacro.h b/portable/GCC/ARM7_LPC23xx/portmacro.h index 5b78481e3..3f2242fa9 100644 --- a/portable/GCC/ARM7_LPC23xx/portmacro.h +++ b/portable/GCC/ARM7_LPC23xx/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/Arm_AARCH64/README.md b/portable/GCC/ARM_AARCH64/README.md similarity index 90% rename from portable/GCC/Arm_AARCH64/README.md rename to portable/GCC/ARM_AARCH64/README.md index 70552c202..60f670177 100644 --- a/portable/GCC/Arm_AARCH64/README.md +++ b/portable/GCC/ARM_AARCH64/README.md @@ -13,11 +13,11 @@ the T32 and A32 instruction sets. Follow the [link](https://developer.arm.com/Architectures/A-Profile%20Architecture) for more information. -## Arm_AARCH64 port +## ARM_AARCH64 port This port adds support for Armv8-A architecture AArch64 execution state. This port is generic and can be used as a starting point for Armv8-A application processors. -* Arm_AARCH64 - * Memory mapped interace to access Arm GIC registers +* ARM_AARCH64 + * Memory mapped interface to access Arm GIC registers diff --git a/portable/GCC/Arm_AARCH64/port.c b/portable/GCC/ARM_AARCH64/port.c similarity index 90% rename from portable/GCC/Arm_AARCH64/port.c rename to portable/GCC/ARM_AARCH64/port.c index 8c2af2dc7..7f080db74 100644 --- a/portable/GCC/Arm_AARCH64/port.c +++ b/portable/GCC/ARM_AARCH64/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -133,6 +133,10 @@ #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) #define portBIT_0_SET ( ( uint8_t ) 0x01 ) +/* The space on the stack required to hold the FPU registers. + * There are 32 128-bit registers.*/ +#define portFPU_REGISTER_WORDS ( 32 * 2 ) + /*-----------------------------------------------------------*/ /* @@ -244,23 +248,47 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ - pxTopOfStack--; + pxTopOfStack--; *pxTopOfStack = portINITIAL_PSTATE; - pxTopOfStack--; + pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ - pxTopOfStack--; - /* The task will start with a critical nesting count of 0 as interrupts are - * enabled. */ - *pxTopOfStack = portNO_CRITICAL_NESTING; - pxTopOfStack--; + #if ( configUSE_TASK_FPU_SUPPORT == 1 ) + { + /* The task will start with a critical nesting count of 0 as interrupts are + * enabled. */ + pxTopOfStack--; + *pxTopOfStack = portNO_CRITICAL_NESTING; - /* The task will start without a floating point context. A task that uses - * the floating point hardware must call vPortTaskUsesFPU() before executing - * any floating point instructions. */ - *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + /* The task will start without a floating point context. A task that + * uses the floating point hardware must call vPortTaskUsesFPU() before + * executing any floating point instructions. */ + pxTopOfStack--; + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + } + #elif ( configUSE_TASK_FPU_SUPPORT == 2 ) + { + /* The task will start with a floating point context. Leave enough + * space for the registers - and ensure they are initialised to 0. */ + pxTopOfStack -= portFPU_REGISTER_WORDS; + memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); + + /* The task will start with a critical nesting count of 0 as interrupts are + * enabled. */ + pxTopOfStack--; + *pxTopOfStack = portNO_CRITICAL_NESTING; + + pxTopOfStack--; + *pxTopOfStack = pdTRUE; + ullPortTaskHasFPUContext = pdTRUE; + } + #else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */ + { + #error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined." + } + #endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */ return pxTopOfStack; } @@ -440,15 +468,19 @@ void FreeRTOS_Tick_Handler( void ) } /*-----------------------------------------------------------*/ -void vPortTaskUsesFPU( void ) -{ - /* A task is registering the fact that it needs an FPU context. Set the - * FPU flag (which is saved as part of the task context). */ - ullPortTaskHasFPUContext = pdTRUE; +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) - /* Consider initialising the FPSR here - but probably not necessary in - * AArch64. */ -} + void vPortTaskUsesFPU( void ) + { + /* A task is registering the fact that it needs an FPU context. Set the + * FPU flag (which is saved as part of the task context). */ + ullPortTaskHasFPUContext = pdTRUE; + + /* Consider initialising the FPSR here - but probably not necessary in + * AArch64. */ + } + +#endif /* configUSE_TASK_FPU_SUPPORT */ /*-----------------------------------------------------------*/ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) @@ -515,7 +547,7 @@ UBaseType_t uxPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/GCC/Arm_AARCH64/portASM.S b/portable/GCC/ARM_AARCH64/portASM.S similarity index 99% rename from portable/GCC/Arm_AARCH64/portASM.S rename to portable/GCC/ARM_AARCH64/portASM.S index c98cadb11..e684755bf 100644 --- a/portable/GCC/Arm_AARCH64/portASM.S +++ b/portable/GCC/ARM_AARCH64/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/Arm_AARCH64/portmacro.h b/portable/GCC/ARM_AARCH64/portmacro.h similarity index 93% rename from portable/GCC/Arm_AARCH64/portmacro.h rename to portable/GCC/ARM_AARCH64/portmacro.h index 2c9da1c60..0091357ee 100644 --- a/portable/GCC/Arm_AARCH64/portmacro.h +++ b/portable/GCC/ARM_AARCH64/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -135,9 +135,18 @@ extern void vPortInstallFreeRTOSVectorTable( void ); * handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); -/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() - * before any floating point instructions are executed. */ -void vPortTaskUsesFPU( void ); +/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are + * created without an FPU context and must call vPortTaskUsesFPU() to give + * themselves an FPU context before using any FPU instructions. If + * configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context + * by default. */ +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) + void vPortTaskUsesFPU( void ); +#else + /* Each task has an FPU context already, so define this function away to + * nothing to prevent it from being called accidentally. */ + #define vPortTaskUsesFPU() +#endif #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) @@ -160,7 +169,7 @@ void vPortTaskUsesFPU( void ); #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ diff --git a/portable/GCC/Arm_AARCH64_SRE/README.md b/portable/GCC/ARM_AARCH64_SRE/README.md similarity index 89% rename from portable/GCC/Arm_AARCH64_SRE/README.md rename to portable/GCC/ARM_AARCH64_SRE/README.md index 0b2e0e485..129b0e3ec 100644 --- a/portable/GCC/Arm_AARCH64_SRE/README.md +++ b/portable/GCC/ARM_AARCH64_SRE/README.md @@ -13,11 +13,11 @@ the T32 and A32 instruction sets. Follow the [link](https://developer.arm.com/Architectures/A-Profile%20Architecture) for more information. -## Arm_AARCH64_SRE port +## ARM_AARCH64_SRE port This port adds support for Armv8-A architecture AArch64 execution state. This port is generic and can be used as a starting point for Armv8-A application processors. -* Arm_AARCH64_SRE - * System Register interace to access Arm GIC registers +* ARM_AARCH64_SRE + * System Register interface to access Arm GIC registers diff --git a/portable/GCC/Arm_AARCH64_SRE/port.c b/portable/GCC/ARM_AARCH64_SRE/port.c similarity index 85% rename from portable/GCC/Arm_AARCH64_SRE/port.c rename to portable/GCC/ARM_AARCH64_SRE/port.c index 8731054bc..ab9290d43 100644 --- a/portable/GCC/Arm_AARCH64_SRE/port.c +++ b/portable/GCC/ARM_AARCH64_SRE/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -121,6 +121,10 @@ ::"r" ( portUNMASK_VALUE ) ); \ } +/* The space on the stack required to hold the FPU registers. + * There are 32 128-bit plus 2 64-bit status registers.*/ +#define portFPU_REGISTER_WORDS ( (32 * 2) + 2 ) + /*-----------------------------------------------------------*/ /* @@ -129,6 +133,27 @@ */ extern void vPortRestoreTaskContext( void ); +/* + * If the application provides an implementation of vApplicationIRQHandler(), + * then it will get called directly without saving the FPU registers on + * interrupt entry, and this weak implementation of + * vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors - + * it should never actually get called so its implementation contains a + * call to configASSERT() that will always fail. + * + * If the application provides its own implementation of + * vApplicationFPUSafeIRQHandler() then the implementation of + * vApplicationIRQHandler() provided in portASM.S will save the FPU registers + * before calling it. + * + * Therefore, if the application writer wants FPU registers to be saved on + * interrupt entry their IRQ handler must be called + * vApplicationFPUSafeIRQHandler(), and if the application writer does not want + * FPU registers to be saved on interrupt entry their IRQ handler must be + * called vApplicationIRQHandler(). + */ +void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) ); + /*-----------------------------------------------------------*/ /* A variable is used to keep track of the critical section nesting. This @@ -229,23 +254,47 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ - pxTopOfStack--; + pxTopOfStack--; *pxTopOfStack = portINITIAL_PSTATE; - pxTopOfStack--; + pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ - pxTopOfStack--; - /* The task will start with a critical nesting count of 0 as interrupts are - * enabled. */ - *pxTopOfStack = portNO_CRITICAL_NESTING; - pxTopOfStack--; + #if ( configUSE_TASK_FPU_SUPPORT == 1 ) + { + /* The task will start with a critical nesting count of 0 as interrupts are + * enabled. */ + pxTopOfStack--; + *pxTopOfStack = portNO_CRITICAL_NESTING; - /* The task will start without a floating point context. A task that uses - * the floating point hardware must call vPortTaskUsesFPU() before executing - * any floating point instructions. */ - *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + /* The task will start without a floating point context. A task that + * uses the floating point hardware must call vPortTaskUsesFPU() before + * executing any floating point instructions. */ + pxTopOfStack--; + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + } + #elif ( configUSE_TASK_FPU_SUPPORT == 2 ) + { + /* The task will start with a floating point context. Leave enough + * space for the registers - and ensure they are initialised to 0. */ + pxTopOfStack -= portFPU_REGISTER_WORDS; + memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); + + /* The task will start with a critical nesting count of 0 as interrupts are + * enabled. */ + pxTopOfStack--; + *pxTopOfStack = portNO_CRITICAL_NESTING; + + pxTopOfStack--; + *pxTopOfStack = pdTRUE; + ullPortTaskHasFPUContext = pdTRUE; + } + #else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */ + { + #error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined." + } + #endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */ return pxTopOfStack; } @@ -384,6 +433,8 @@ void FreeRTOS_Tick_Handler( void ) } /*-----------------------------------------------------------*/ +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) + void vPortTaskUsesFPU( void ) { /* A task is registering the fact that it needs an FPU context. Set the @@ -393,6 +444,8 @@ void vPortTaskUsesFPU( void ) /* Consider initialising the FPSR here - but probably not necessary in * AArch64. */ } + +#endif /* configUSE_TASK_FPU_SUPPORT */ /*-----------------------------------------------------------*/ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) @@ -463,3 +516,9 @@ UBaseType_t uxPortSetInterruptMask( void ) #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ + +void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) +{ + ( void ) ulICCIAR; + configASSERT( ( volatile void * ) NULL ); +} diff --git a/portable/GCC/Arm_AARCH64_SRE/portASM.S b/portable/GCC/ARM_AARCH64_SRE/portASM.S similarity index 79% rename from portable/GCC/Arm_AARCH64_SRE/portASM.S rename to portable/GCC/ARM_AARCH64_SRE/portASM.S index d779890bc..f1f59cd33 100644 --- a/portable/GCC/Arm_AARCH64_SRE/portASM.S +++ b/portable/GCC/ARM_AARCH64_SRE/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -87,7 +87,7 @@ LDR X0, ullPortTaskHasFPUContextConst LDR X2, [X0] - /* Save the FPU context, if any (32 128-bit registers). */ + /* Save the FPU context, if any (32 128-bit plus two 64-bit status registers). */ CMP X2, #0 B.EQ 1f STP Q0, Q1, [SP,#-0x20]! @@ -107,6 +107,11 @@ STP Q28, Q29, [SP,#-0x20]! STP Q30, Q31, [SP,#-0x20]! + /* Even though upper 32 bits of FPSR and FPCR are reserved, save and restore the whole 64 bits to keep 16-byte SP alignement. */ + MRS X9, FPSR + MRS X10, FPCR + STP X9, X10, [SP, #-0x10]! + 1: /* Store the critical nesting count and FPU context indicator. */ STP X2, X3, [SP, #-0x10]! @@ -157,6 +162,7 @@ /* Restore the FPU context, if any. */ CMP X2, #0 B.EQ 1f + LDP X9, X10, [SP], #0x10 LDP Q30, Q31, [SP], #0x20 LDP Q28, Q29, [SP], #0x20 LDP Q26, Q27, [SP], #0x20 @@ -173,6 +179,8 @@ LDP Q4, Q5, [SP], #0x20 LDP Q2, Q3, [SP], #0x20 LDP Q0, Q1, [SP], #0x20 + MSR FPSR, X9 + MSR FPCR, X10 1: LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ @@ -406,8 +414,82 @@ Exit_IRQ_No_Context_Switch: ERET +/****************************************************************************** + * If the application provides an implementation of vApplicationIRQHandler(), + * then it will get called directly without saving the FPU registers on + * interrupt entry, and this weak implementation of + * vApplicationIRQHandler() will not get called. + * + * If the application provides its own implementation of + * vApplicationFPUSafeIRQHandler() then this implementation of + * vApplicationIRQHandler() will be called, save the FPU registers, and then + * call vApplicationFPUSafeIRQHandler(). + * + * Therefore, if the application writer wants FPU registers to be saved on + * interrupt entry their IRQ handler must be called + * vApplicationFPUSafeIRQHandler(), and if the application writer does not want + * FPU registers to be saved on interrupt entry their IRQ handler must be + * called vApplicationIRQHandler(). + *****************************************************************************/ +.align 8 +.weak vApplicationIRQHandler +.type vApplicationIRQHandler, %function +vApplicationIRQHandler: + /* Save LR and FP on the stack */ + STP X29, X30, [SP, #-0x10]! + /* Save FPU registers (32 128-bits + 2 64-bits configuration and status registers) */ + STP Q0, Q1, [SP,#-0x20]! + STP Q2, Q3, [SP,#-0x20]! + STP Q4, Q5, [SP,#-0x20]! + STP Q6, Q7, [SP,#-0x20]! + STP Q8, Q9, [SP,#-0x20]! + STP Q10, Q11, [SP,#-0x20]! + STP Q12, Q13, [SP,#-0x20]! + STP Q14, Q15, [SP,#-0x20]! + STP Q16, Q17, [SP,#-0x20]! + STP Q18, Q19, [SP,#-0x20]! + STP Q20, Q21, [SP,#-0x20]! + STP Q22, Q23, [SP,#-0x20]! + STP Q24, Q25, [SP,#-0x20]! + STP Q26, Q27, [SP,#-0x20]! + STP Q28, Q29, [SP,#-0x20]! + STP Q30, Q31, [SP,#-0x20]! + + /* Even though upper 32 bits of FPSR and FPCR are reserved, save and restore the whole 64 bits to keep 16-byte SP alignement. */ + MRS X9, FPSR + MRS X10, FPCR + STP X9, X10, [SP, #-0x10]! + + /* Call the C handler. */ + BL vApplicationFPUSafeIRQHandler + + /* Restore FPU registers */ + + LDP X9, X10, [SP], #0x10 + LDP Q30, Q31, [SP], #0x20 + LDP Q28, Q29, [SP], #0x20 + LDP Q26, Q27, [SP], #0x20 + LDP Q24, Q25, [SP], #0x20 + LDP Q22, Q23, [SP], #0x20 + LDP Q20, Q21, [SP], #0x20 + LDP Q18, Q19, [SP], #0x20 + LDP Q16, Q17, [SP], #0x20 + LDP Q14, Q15, [SP], #0x20 + LDP Q12, Q13, [SP], #0x20 + LDP Q10, Q11, [SP], #0x20 + LDP Q8, Q9, [SP], #0x20 + LDP Q6, Q7, [SP], #0x20 + LDP Q4, Q5, [SP], #0x20 + LDP Q2, Q3, [SP], #0x20 + LDP Q0, Q1, [SP], #0x20 + MSR FPSR, X9 + MSR FPCR, X10 + + /* Restore FP and LR */ + LDP X29, X30, [SP], #0x10 + RET .align 8 pxCurrentTCBConst: .dword pxCurrentTCB diff --git a/portable/GCC/Arm_AARCH64_SRE/portmacro.h b/portable/GCC/ARM_AARCH64_SRE/portmacro.h similarity index 91% rename from portable/GCC/Arm_AARCH64_SRE/portmacro.h rename to portable/GCC/ARM_AARCH64_SRE/portmacro.h index cbe0b54dd..5810741d2 100644 --- a/portable/GCC/Arm_AARCH64_SRE/portmacro.h +++ b/portable/GCC/ARM_AARCH64_SRE/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -135,9 +135,18 @@ extern void vPortInstallFreeRTOSVectorTable( void ); * handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); -/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() - * before any floating point instructions are executed. */ -void vPortTaskUsesFPU( void ); +/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are + * created without an FPU context and must call vPortTaskUsesFPU() to give + * themselves an FPU context before using any FPU instructions. If + * configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context + * by default. */ +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) + void vPortTaskUsesFPU( void ); +#else + /* Each task has an FPU context already, so define this function away to + * nothing to prevent it from being called accidentally. */ + #define vPortTaskUsesFPU() +#endif #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) @@ -160,7 +169,7 @@ void vPortTaskUsesFPU( void ); #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ diff --git a/portable/GCC/ARM_CA53_64_BIT/README.md b/portable/GCC/ARM_CA53_64_BIT/README.md index b3d56c040..578b475d9 100644 --- a/portable/GCC/ARM_CA53_64_BIT/README.md +++ b/portable/GCC/ARM_CA53_64_BIT/README.md @@ -4,13 +4,13 @@ Initial port to support Armv8-A architecture in FreeRTOS kernel was written for Arm Cortex-A53 processor. * ARM_CA53_64_BIT - * Memory mapped interace to access Arm GIC registers + * Memory mapped interface to access Arm GIC registers This port is generic and can be used as a starting point for other Armv8-A application processors. Therefore, the port `ARM_CA53_64_BIT` is renamed as -`Arm_AARCH64`. The existing projects that use old port `ARM_CA53_64_BIT`, -should migrate to renamed port `Arm_AARCH64`. +`ARM_AARCH64`. The existing projects that use old port `ARM_CA53_64_BIT`, +should migrate to renamed port `ARM_AARCH64`. **NOTE** -This port uses memory mapped interace to access Arm GIC registers. +This port uses memory mapped interface to access Arm GIC registers. diff --git a/portable/GCC/ARM_CA53_64_BIT_SRE/README.md b/portable/GCC/ARM_CA53_64_BIT_SRE/README.md index fb5d7936a..9951f81c8 100644 --- a/portable/GCC/ARM_CA53_64_BIT_SRE/README.md +++ b/portable/GCC/ARM_CA53_64_BIT_SRE/README.md @@ -4,13 +4,13 @@ Initial port to support Armv8-A architecture in FreeRTOS kernel was written for Arm Cortex-A53 processor. * ARM_CA53_64_BIT_SRE - * System Register interace to access Arm GIC registers + * System Register interface to access Arm GIC registers This port is generic and can be used as a starting point for other Armv8-A -application processors. Therefore, the port `Arm_AARCH64_SRE` is renamed as -`Arm_AARCH64_SRE`. The existing projects that use old port `Arm_AARCH64_SRE`, -should migrate to renamed port `Arm_AARCH64_SRE`. +application processors. Therefore, the port `ARM_AARCH64_SRE` is renamed as +`ARM_AARCH64_SRE`. The existing projects that use old port `ARM_AARCH64_SRE`, +should migrate to renamed port `ARM_AARCH64_SRE`. **NOTE** -This port uses System Register interace to access Arm GIC registers. +This port uses System Register interface to access Arm GIC registers. diff --git a/portable/GCC/ARM_CA9/port.c b/portable/GCC/ARM_CA9/port.c index 4e4189d36..67bb0fc8c 100644 --- a/portable/GCC/ARM_CA9/port.c +++ b/portable/GCC/ARM_CA9/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -208,9 +208,9 @@ volatile uint32_t ulPortYieldRequired = pdFALSE; volatile uint32_t ulPortInterruptNesting = 0UL; /* Used in the asm file. */ -__attribute__( ( used ) ) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS; -__attribute__( ( used ) ) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS; -__attribute__( ( used ) ) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS; +__attribute__( ( used ) ) const uint32_t ulICCIARAddress = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS; +__attribute__( ( used ) ) const uint32_t ulICCEOIRAddress = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS; +__attribute__( ( used ) ) const uint32_t ulICCPMRAddress = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS; __attribute__( ( used ) ) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); /*-----------------------------------------------------------*/ @@ -562,7 +562,7 @@ uint32_t ulPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/GCC/ARM_CA9/portASM.S b/portable/GCC/ARM_CA9/portASM.S index 55baabbd3..5df123479 100644 --- a/portable/GCC/ARM_CA9/portASM.S +++ b/portable/GCC/ARM_CA9/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -33,10 +33,10 @@ .set SVC_MODE, 0x13 .set IRQ_MODE, 0x12 - /* Hardware registers. */ - .extern ulICCIAR - .extern ulICCEOIR - .extern ulICCPMR + /* Hardware registers addresses. */ + .extern ulICCIARAddress + .extern ulICCEOIRAddress + .extern ulICCPMRAddress /* Variables and functions. */ .extern ulMaxAPIPriorityMask @@ -246,7 +246,7 @@ exit_without_switch: MOVS PC, LR switch_before_exit: - /* A context swtich is to be performed. Clear the context switch pending + /* A context switch is to be performed. Clear the context switch pending flag. */ MOV r0, #0 STR r0, [r1] @@ -302,7 +302,7 @@ switch_before_exit: vApplicationIRQHandler: PUSH {LR} FMRX R1, FPSCR - VPUSH {D0-D15} + VPUSH {D0-D7} VPUSH {D16-D31} PUSH {R1} @@ -311,15 +311,15 @@ vApplicationIRQHandler: POP {R0} VPOP {D16-D31} - VPOP {D0-D15} + VPOP {D0-D7} VMSR FPSCR, R0 POP {PC} -ulICCIARConst: .word ulICCIAR -ulICCEOIRConst: .word ulICCEOIR -ulICCPMRConst: .word ulICCPMR +ulICCIARConst: .word ulICCIARAddress +ulICCEOIRConst: .word ulICCEOIRAddress +ulICCPMRConst: .word ulICCPMRAddress pxCurrentTCBConst: .word pxCurrentTCB ulCriticalNestingConst: .word ulCriticalNesting ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext diff --git a/portable/GCC/ARM_CA9/portmacro.h b/portable/GCC/ARM_CA9/portmacro.h index bd9b36dd9..1ded79c8c 100644 --- a/portable/GCC/ARM_CA9/portmacro.h +++ b/portable/GCC/ARM_CA9/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -157,7 +157,7 @@ void FreeRTOS_Tick_Handler( void ); #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ diff --git a/portable/GCC/ARM_CM0/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM0/mpu_wrappers_v2_asm.c new file mode 100644 index 000000000..4f14482e2 --- /dev/null +++ b/portable/GCC/ARM_CM0/mpu_wrappers_v2_asm.c @@ -0,0 +1,2217 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" +#include "mpu_syscall_numbers.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( INCLUDE_xTaskDelayUntil == 1 ) + + BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskDelayUntilImpl \n" + " pop {pc} \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" + ); + } + + #endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskAbortDelayImpl \n" + " pop {pc} \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" + ); + } + + #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskDelay == 1 ) + + void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " push {lr} \n" + " blx MPU_vTaskDelayImpl \n" + " pop {pc} \n" + " MPU_vTaskDelay_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" + ); + } + + #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " push {lr} \n" + " blx MPU_uxTaskPriorityGetImpl \n" + " pop {pc} \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" + ); + } + + #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_eTaskGetState == 1 ) + + eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " push {lr} \n" + " blx MPU_eTaskGetStateImpl \n" + " pop {pc} \n" + " MPU_eTaskGetState_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" + ); + } + + #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " push {lr} \n" + " blx MPU_vTaskGetInfoImpl \n" + " pop {pc} \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" + ); + } + + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGetIdleTaskHandleImpl \n" + " pop {pc} \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" + ); + } + + #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + + void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " push {lr} \n" + " blx MPU_vTaskSuspendImpl \n" + " pop {pc} \n" + " MPU_vTaskSuspend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" + ); + } + + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + + void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " push {lr} \n" + " blx MPU_vTaskResumeImpl \n" + " pop {pc} \n" + " MPU_vTaskResume_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" + ); + } + + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + TickType_t MPU_xTaskGetTickCount( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGetTickCountImpl \n" + " pop {pc} \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " push {lr} \n" + " blx MPU_uxTaskGetNumberOfTasksImpl \n" + " pop {pc} \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " push {lr} \n" + " blx MPU_ulTaskGetRunTimeCounterImpl \n" + " pop {pc} \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" + ); + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " push {lr} \n" + " blx MPU_ulTaskGetRunTimePercentImpl \n" + " pop {pc} \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" + ); + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " push {lr} \n" + " blx MPU_ulTaskGetIdleRunTimePercentImpl \n" + " pop {pc} \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" + ); + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " push {lr} \n" + " blx MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " pop {pc} \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" + ); + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " push {lr} \n" + " blx MPU_vTaskSetApplicationTaskTagImpl \n" + " pop {pc} \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" + ); + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGetApplicationTaskTagImpl \n" + " pop {pc} \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" + ); + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " push {lr} \n" + " blx MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " pop {pc} \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" + ); + } + + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " push {lr} \n" + " blx MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " pop {pc} \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" + ); + } + + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " push {lr} \n" + " blx MPU_uxTaskGetSystemStateImpl \n" + " pop {pc} \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" + ); + } + + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " push {lr} \n" + " blx MPU_uxTaskGetStackHighWaterMarkImpl \n" + " pop {pc} \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" + ); + } + + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " push {lr} \n" + " blx MPU_uxTaskGetStackHighWaterMark2Impl \n" + " pop {pc} \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" + ); + } + + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGetCurrentTaskHandleImpl \n" + " pop {pc} \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" + ); + } + + #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetSchedulerState == 1 ) + + BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGetSchedulerStateImpl \n" + " pop {pc} \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" + ); + } + + #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + + void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " push {lr} \n" + " blx MPU_vTaskSetTimeOutStateImpl \n" + " pop {pc} \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskCheckForTimeOutImpl \n" + " pop {pc} \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGenericNotifyImpl \n" + " pop {pc} \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" + ); + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGenericNotifyWaitImpl \n" + " pop {pc} \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" + ); + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " push {lr} \n" + " blx MPU_ulTaskGenericNotifyTakeImpl \n" + " pop {pc} \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" + ); + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " push {lr} \n" + " blx MPU_xTaskGenericNotifyStateClearImpl \n" + " pop {pc} \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" + ); + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " push {lr} \n" + " blx MPU_ulTaskGenericNotifyValueClearImpl \n" + " pop {pc} \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" + ); + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueGenericSendImpl \n" + " pop {pc} \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " push {lr} \n" + " blx MPU_uxQueueMessagesWaitingImpl \n" + " pop {pc} \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " push {lr} \n" + " blx MPU_uxQueueSpacesAvailableImpl \n" + " pop {pc} \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueReceiveImpl \n" + " pop {pc} \n" + " MPU_xQueueReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " push {lr} \n" + " blx MPU_xQueuePeekImpl \n" + " pop {pc} \n" + " MPU_xQueuePeek_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueSemaphoreTakeImpl \n" + " pop {pc} \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueGetMutexHolderImpl \n" + " pop {pc} \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" + ); + } + + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueTakeMutexRecursiveImpl \n" + " pop {pc} \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" + ); + } + + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueGiveMutexRecursiveImpl \n" + " pop {pc} \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" + ); + } + + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueSelectFromSetImpl \n" + " pop {pc} \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" + ); + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " push {lr} \n" + " blx MPU_xQueueAddToSetImpl \n" + " pop {pc} \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" + ); + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " push {lr} \n" + " blx MPU_vQueueAddToRegistryImpl \n" + " pop {pc} \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" + ); + } + + #endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " push {lr} \n" + " blx MPU_vQueueUnregisterQueueImpl \n" + " pop {pc} \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" + ); + } + + #endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + + const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " push {lr} \n" + " blx MPU_pcQueueGetNameImpl \n" + " pop {pc} \n" + " MPU_pcQueueGetName_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" + ); + } + + #endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " push {lr} \n" + " blx MPU_pvTimerGetTimerIDImpl \n" + " pop {pc} \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " push {lr} \n" + " blx MPU_vTimerSetTimerIDImpl \n" + " pop {pc} \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " push {lr} \n" + " blx MPU_xTimerIsTimerActiveImpl \n" + " pop {pc} \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " push {lr} \n" + " blx MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " pop {pc} \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGenericCommandFromTaskEntry( const xTimerGenericCommandFromTaskParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTimerGenericCommandFromTaskEntry( const xTimerGenericCommandFromTaskParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " push {lr} \n" + " blx MPU_xTimerGenericCommandFromTaskImpl \n" + " pop {pc} \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " push {lr} \n" + " blx MPU_pcTimerGetNameImpl \n" + " pop {pc} \n" + " MPU_pcTimerGetName_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " push {lr} \n" + " blx MPU_vTimerSetReloadModeImpl \n" + " pop {pc} \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " push {lr} \n" + " blx MPU_xTimerGetReloadModeImpl \n" + " pop {pc} \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " push {lr} \n" + " blx MPU_uxTimerGetReloadModeImpl \n" + " pop {pc} \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " push {lr} \n" + " blx MPU_xTimerGetPeriodImpl \n" + " pop {pc} \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " push {lr} \n" + " blx MPU_xTimerGetExpiryTimeImpl \n" + " pop {pc} \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" + ); + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " push {lr} \n" + " blx MPU_xEventGroupWaitBitsImpl \n" + " pop {pc} \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " push {lr} \n" + " blx MPU_xEventGroupClearBitsImpl \n" + " pop {pc} \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " push {lr} \n" + " blx MPU_xEventGroupSetBitsImpl \n" + " pop {pc} \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " push {lr} \n" + " blx MPU_xEventGroupSyncImpl \n" + " pop {pc} \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " push {lr} \n" + " blx MPU_uxEventGroupGetNumberImpl \n" + " pop {pc} \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" + ); + } + + #endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " push {lr} \n" + " blx MPU_vEventGroupSetNumberImpl \n" + " pop {pc} \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" + ); + } + + #endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferSendImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferReceiveImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferIsFullImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferIsEmptyImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferSpacesAvailableImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferBytesAvailableImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferSetTriggerLevelImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " push {lr} \n" + " blx MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " pop {pc} \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM0/port.c b/portable/GCC/ARM_CM0/port.c index 53bc33a41..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 (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -26,54 +28,195 @@ * */ -/*----------------------------------------------------------- -* Implementation of functions defined in portable.h for the ARM CM0 port. -*----------------------------------------------------------*/ +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" -/* Prototype of all Interrupt Service Routines (ISRs). */ +/* MPU includes. */ +#include "mpu_wrappers.h" +#include "mpu_syscall_numbers.h" + +/* Portasm includes. */ +#include "portasm.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/*-----------------------------------------------------------*/ + +/** + * @brief Prototype of all Interrupt Service Routines (ISRs). + */ typedef void ( * portISR_t )( void ); -/* Constants required to manipulate the NVIC. */ +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the NVIC. + */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) -#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) -#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) -#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) ) #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) -#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) -#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) +#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) -/* Constants used to check the installation of the FreeRTOS interrupt handlers. */ +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the SCB. + */ #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) -#define portVECTOR_INDEX_PENDSV ( 14 ) +#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) +#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) -/* Constants required to set up the initial stack. */ -#define portINITIAL_XPSR ( 0x01000000 ) +/*-----------------------------------------------------------*/ -/* The systick is a 24-bit counter. */ -#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) +/** + * @brief Constants used to check the installation of the FreeRTOS interrupt handlers. + */ +#define portVECTOR_INDEX_SVC ( 11 ) +#define portVECTOR_INDEX_PENDSV ( 14 ) -/* A fiddle factor to estimate the number of SysTick counts that would have - * occurred while the SysTick counter is stopped during tickless idle - * calculations. */ -#ifndef portMISSED_COUNTS_FACTOR - #define portMISSED_COUNTS_FACTOR ( 94UL ) -#endif +/*-----------------------------------------------------------*/ -/* Let the user override the default SysTick clock rate. If defined by the +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) + +/*-----------------------------------------------------------*/ + +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) + +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to manipulate the MPU. + */ +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) + +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RASR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) + +/* MPU Region Attribute and Size Register (RASR) bitmasks. */ +#define portMPU_RASR_AP_BITMASK ( 0x7UL << 24UL ) +#define portMPU_RASR_S_C_B_BITMASK ( 0x7UL ) +#define portMPU_RASR_S_C_B_LOCATION ( 16UL ) +#define portMPU_RASR_SIZE_BITMASK ( 0x1FUL << 1UL ) +#define portMPU_RASR_REGION_ENABLE_BITMASK ( 0x1UL ) + +/* MPU Region Base Address Register (RBAR) bitmasks. */ +#define portMPU_RBAR_ADDRESS_BITMASK ( 0xFFFFFF00UL ) +#define portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ( 0x1UL << 4UL ) +#define portMPU_RBAR_REGION_NUMBER_BITMASK ( 0x0000000FUL ) + +/* MPU Control Register (MPU_CTRL) bitmasks. */ +#define portMPU_CTRL_ENABLE_BITMASK ( 0x1UL ) +#define portMPU_CTRL_PRIV_BACKGROUND_ENABLE_BITMASK ( 0x1UL << 2UL ) /* PRIVDEFENA bit. */ + +/* Expected value of the portMPU_TYPE register. */ +#define portEXPECTED_MPU_TYPE_VALUE ( 0x8UL << 8UL ) /* 8 DREGION unified. */ + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_BITMASK ) + +/* Extract size of the MPU region as encoded in the + * RASR (Region Attribute and Size Register) value. */ +#define portEXTRACT_REGION_SIZE_FROM_RASR( rasr ) \ + ( 1 << ( ( ( ( rasr ) & portMPU_RASR_SIZE_BITMASK ) >> 1 )+ 1 ) ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* Max value that fits in a uint32_t type. */ +#define portUINT32_MAX ( ~( ( uint32_t ) 0 ) ) + +/* Check if adding a and b will result in overflow. */ +#define portADD_UINT32_WILL_OVERFLOW( a, b ) ( ( a ) > ( portUINT32_MAX - ( b ) ) ) + +/*-----------------------------------------------------------*/ + +/** + * @brief The maximum 24-bit number. + * + * It is needed because the systick is a 24-bit counter. + */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/** + * @brief A fiddle factor to estimate the number of SysTick counts that would + * have occurred while the SysTick counter is stopped during tickless idle + * calculations. + */ +#define portMISSED_COUNTS_FACTOR ( 94UL ) + +/*-----------------------------------------------------------*/ + +/** + * @brief Constants required to set up the initial stack. + */ +#define portINITIAL_XPSR ( 0x01000000 ) + +/** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * 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 --> Reserved, 1. + */ +#define portINITIAL_EXC_RETURN ( 0xfffffffdUL ) + +/** + * @brief CONTROL register privileged bit mask. + * + * Bit[0] in CONTROL register tells the privilege: + * Bit[0] = 0 ==> The task is privileged. + * Bit[0] = 1 ==> The task is not privileged. + */ +#define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL ) + +/** + * @brief Initial CONTROL register values. + */ +#define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 ) +#define portINITIAL_CONTROL_PRIVILEGED ( 0x2 ) + +/** + * @brief Let the user override the default SysTick clock rate. If defined by the * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the - * configuration register. */ + * configuration register. + */ #ifndef configSYSTICK_CLOCK_HZ #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) /* Ensure the SysTick is clocked at the same frequency as the core. */ @@ -83,381 +226,169 @@ typedef void ( * portISR_t )( void ); #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) #endif -/* Let the user override the pre-loading of the initial LR with the address of - * prvTaskExitError() in case it messes up unwinding of the stack in the - * debugger. */ +/** + * @brief Let the user override the pre-loading of the initial LR with the + * address of prvTaskExitError() in case it messes up unwinding of the stack + * in the debugger. + */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif -/* - * Setup the timer to generate the tick interrupts. The implementation in this - * file is weak to allow application writers to change the timer used to - * generate the tick interrupt. +/** + * @brief If portPRELOAD_REGISTERS then registers will be given an initial value + * when a task is created. This helps in debugging at the cost of code size. */ -void vPortSetupTimerInterrupt( void ); +#define portPRELOAD_REGISTERS 1 -/* - * Exception handlers. - */ -void xPortPendSVHandler( void ) __attribute__( ( naked ) ); -void xPortSysTickHandler( void ); -void vPortSVCHandler( void ); +/*-----------------------------------------------------------*/ -/* - * Start first task is a separate function so it can be tested in isolation. - */ -static void vPortStartFirstTask( void ) __attribute__( ( naked ) ); - -/* - * Used to catch tasks that attempt to return from their implementing function. +/** + * @brief Used to catch tasks that attempt to return from their implementing + * function. */ static void prvTaskExitError( void ); -/*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) -/* Each task maintains its own interrupt status in the critical nesting - * variable. */ -static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + /** + * @brief Setup the Memory Protection Unit (MPU). + */ + static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; -/*-----------------------------------------------------------*/ +#endif /* configENABLE_MPU */ -/* - * The number of SysTick increments that make up one tick period. +/** + * @brief Setup the timer to generate the tick interrupts. + * + * The implementation in this file is weak to allow application writers to + * change the timer used to generate the tick interrupt. */ -#if ( configUSE_TICKLESS_IDLE == 1 ) - static uint32_t ulTimerCountsForOneTick = 0; -#endif /* configUSE_TICKLESS_IDLE */ +void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; -/* - * The maximum number of tick periods that can be suppressed is limited by the - * 24 bit resolution of the SysTick timer. +/** + * @brief Checks whether the current execution context is interrupt. + * + * @return pdTRUE if the current execution context is interrupt, pdFALSE + * otherwise. */ -#if ( configUSE_TICKLESS_IDLE == 1 ) - static uint32_t xMaximumPossibleSuppressedTicks = 0; -#endif /* configUSE_TICKLESS_IDLE */ +BaseType_t xPortIsInsideInterrupt( void ); -/* - * Compensate for the CPU cycles that pass while the SysTick is stopped (low - * power functionality only. +/** + * @brief Yield the processor. */ -#if ( configUSE_TICKLESS_IDLE == 1 ) - static uint32_t ulStoppedTimerCompensation = 0; -#endif /* configUSE_TICKLESS_IDLE */ +void vPortYield( void ) PRIVILEGED_FUNCTION; -/*-----------------------------------------------------------*/ - -/* - * See header file for description. +/** + * @brief Enter critical section. */ -StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters ) -{ - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - 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--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 8; /* R11..R4. */ +void vPortEnterCritical( void ) PRIVILEGED_FUNCTION; - return pxTopOfStack; -} -/*-----------------------------------------------------------*/ +/** + * @brief Exit from critical section. + */ +void vPortExitCritical( void ) PRIVILEGED_FUNCTION; -static void prvTaskExitError( void ) -{ - volatile uint32_t ulDummy = 0UL; +/** + * @brief SysTick handler. + */ +void SysTick_Handler( void ) PRIVILEGED_FUNCTION; - /* A function that implements a task must not exit or attempt to return to - * its caller as there is nothing to return to. If a task wants to exit it - * should instead call vTaskDelete( NULL ). +/** + * @brief C part of SVC handler. + */ +portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#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. * - * Artificially force an assert() to be triggered if configASSERT() is - * defined, then stop here so application writers can catch the error. */ - configASSERT( uxCriticalNesting == ~0UL ); - portDISABLE_INTERRUPTS(); + * @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; - while( ulDummy == 0 ) - { - /* This file calls prvTaskExitError() after the scheduler has been - * started to remove a compiler warning about the function being defined - * but never called. ulDummy is used purely to quieten other warnings - * about code appearing after this function is called - making ulDummy - * volatile makes the compiler think the function could return and - * therefore not output an 'unreachable code' warning for code that appears - * after it. */ - } -} -/*-----------------------------------------------------------*/ +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ -void vPortSVCHandler( void ) -{ - /* This function is no longer used, but retained for backward - * compatibility. */ -} -/*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -void vPortStartFirstTask( void ) -{ - /* Don't reset the MSP stack as is done on CM3/4 devices. The vector table - * in some CM0 devices cannot be modified and thus may not hold the - * application's initial MSP value. */ - __asm volatile ( - " .syntax unified \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */ - " ldr r3, [r2] \n" - " ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ - " adds r0, #32 \n" /* Discard everything up to r0. */ - " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ - " movs r0, #2 \n" /* Switch to the psp stack. */ - " msr CONTROL, r0 \n" - " isb \n" - " pop {r0-r5} \n" /* Pop the registers that are saved automatically. */ - " mov lr, r5 \n" /* lr is now in r5. */ - " pop {r3} \n" /* Return address is now in r3. */ - " pop {r2} \n" /* Pop and discard XPSR. */ - " cpsie i \n" /* The first task has its context and interrupts can be enabled. */ - " bx r3 \n" /* Finally, jump to the user defined task code. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB " - ); -} -/*-----------------------------------------------------------*/ + /** + * @brief Raise SVC for exiting from a system call. + */ + void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/* - * See header file for description. - */ -BaseType_t xPortStartScheduler( void ) -{ - /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: - * 1. Direct Routing - Install the function xPortPendSVHandler for PendSV - * interrupt. - * 2. Indirect Routing - Install separate handler for PendSV interrupt and - * route program control from that handler to xPortPendSVHandler 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. * - * Applications that use Indirect Routing must set - * configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct - * routing, which is validated here when configCHECK_HANDLER_INSTALLATION - * is 1, should be preferred when possible. */ - #if ( configCHECK_HANDLER_INSTALLATION == 1 ) - { - /* Point pxVectorTable to the interrupt vector table. Systems without - * a VTOR register provide the value zero in the VTOR register and - * the vector table itself is located at the address 0x00000000. */ - const portISR_t * const pxVectorTable = portSCB_VTOR_REG; + * @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; - /* Validate that the application has correctly installed the FreeRTOS - * handler for PendSV interrupt. We do not check the installation of the - * SysTick handler because the application may choose to drive the RTOS - * tick using a timer other than the SysTick timer by overriding the - * weak function vPortSetupTimerInterrupt(). - * - * Assertion failures here indicate incorrect installation of the - * FreeRTOS handler. For help installing the FreeRTOS handler, see - * https://www.FreeRTOS.org/FAQHelp.html. - * - * Systems with a configurable address for the interrupt vector table - * can also encounter assertion failures or even system faults here if - * VTOR is not set correctly to point to the application's vector table. */ - configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler ); - } - #endif /* configCHECK_HANDLER_INSTALLATION */ +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ - /* Make PendSV and SysTick the lowest priority interrupts. */ - portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; - portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; +#if ( configENABLE_MPU == 1 ) - /* Start the timer that generates the tick ISR. Interrupts are disabled - * here already. */ - vPortSetupTimerInterrupt(); + /** + * @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; - /* Initialise the critical nesting count ready for the first task. */ - uxCriticalNesting = 0; +#endif /* configENABLE_MPU == 1 */ - /* Start the first task. */ - vPortStartFirstTask(); - - /* Should never get here as the tasks will now be executing! Call the task - * exit error function to prevent compiler warnings about a static function - * not being called in the case that the application writer overrides this - * functionality by defining configTASK_RETURN_ADDRESS. Call - * vTaskSwitchContext() so link time optimisation does not remove the - * symbol. */ - vTaskSwitchContext(); - prvTaskExitError(); - - /* Should not get here! */ - return 0; -} /*-----------------------------------------------------------*/ -void vPortEndScheduler( void ) -{ - /* Not implemented in ports where there is nothing to return to. - * Artificially force an assert. */ - configASSERT( uxCriticalNesting == 1000UL ); -} -/*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -void vPortYield( void ) -{ - /* Set a PendSV to request a context switch. */ - portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; - /* Barriers are normally not required but do ensure the code is completely - * within the specified behaviour for the architecture. */ - __asm volatile ( "dsb" ::: "memory" ); - __asm volatile ( "isb" ); -} -/*-----------------------------------------------------------*/ +#endif -void vPortEnterCritical( void ) -{ - portDISABLE_INTERRUPTS(); - uxCriticalNesting++; - __asm volatile ( "dsb" ::: "memory" ); - __asm volatile ( "isb" ); -} -/*-----------------------------------------------------------*/ - -void vPortExitCritical( void ) -{ - configASSERT( uxCriticalNesting ); - uxCriticalNesting--; - - if( uxCriticalNesting == 0 ) - { - portENABLE_INTERRUPTS(); - } -} -/*-----------------------------------------------------------*/ - -uint32_t ulSetInterruptMaskFromISR( void ) -{ - __asm volatile ( - " mrs r0, PRIMASK \n" - " cpsid i \n" - " bx lr " - ::: "memory" - ); -} -/*-----------------------------------------------------------*/ - -void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) -{ - __asm volatile ( - " msr PRIMASK, r0 \n" - " bx lr " - ::: "memory" - ); -} -/*-----------------------------------------------------------*/ - -void xPortPendSVHandler( void ) -{ - /* This is a naked function. */ - - __asm volatile - ( - " .syntax unified \n" - " mrs r0, psp \n" - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ - " ldr r2, [r3] \n" - " \n" - " subs r0, r0, #32 \n" /* Make space for the remaining low registers. */ - " str r0, [r2] \n" /* Save the new top of stack. */ - " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ - " mov r4, r8 \n" /* Store the high registers. */ - " mov r5, r9 \n" - " mov r6, r10 \n" - " mov r7, r11 \n" - " stmia r0!, {r4-r7} \n" - " \n" - " push {r3, r14} \n" - " cpsid i \n" - " bl vTaskSwitchContext \n" - " cpsie i \n" - " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */ - " \n" - " ldr r1, [r2] \n" - " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ - " adds r0, r0, #16 \n" /* Move to the high registers. */ - " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */ - " mov r8, r4 \n" - " mov r9, r5 \n" - " mov r10, r6 \n" - " mov r11, r7 \n" - " \n" - " msr psp, r0 \n" /* Remember the new top of stack for the task. */ - " \n" - " subs r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */ - " ldmia r0!, {r4-r7} \n" /* Pop low registers. */ - " \n" - " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB " - ); -} -/*-----------------------------------------------------------*/ - -void xPortSysTickHandler( void ) -{ - uint32_t ulPreviousMask; - - ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); - traceISR_ENTER(); - { - /* Increment the RTOS tick. */ - if( xTaskIncrementTick() != pdFALSE ) - { - traceISR_EXIT_TO_SCHEDULER(); - /* Pend a context switch. */ - portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; - } - else - { - traceISR_EXIT(); - } - } - portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); -} -/*-----------------------------------------------------------*/ - -/* - * Setup the systick timer to generate the tick interrupts at the required - * frequency. +/** + * @brief Each task maintains its own interrupt status in the critical nesting + * variable. */ -__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) -{ - /* Calculate the constants required to configure the tick interrupt. */ - #if ( configUSE_TICKLESS_IDLE == 1 ) - { - ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); - xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; - ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); - } - #endif /* configUSE_TICKLESS_IDLE */ +PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; - /* Stop and reset the SysTick. */ - portNVIC_SYSTICK_CTRL_REG = 0UL; - portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; +#if ( configUSE_TICKLESS_IDLE == 1 ) + + /** + * @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. + */ + PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; + + /** + * @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 */ - /* Configure SysTick to interrupt at the requested rate. */ - portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; - portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); -} /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) @@ -679,3 +610,1064 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) } #endif /* configUSE_TICKLESS_IDLE */ + +/*-----------------------------------------------------------*/ + +__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if ( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and reset SysTick. + * + * QEMU versions older than 7.0.0 contain a bug which causes an error if we + * enable SysTick without first selecting a valid clock source. We trigger + * the bug if we change clock sources from a clock with a zero clock period + * to one with a nonzero clock period and enable Systick at the same time. + * So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit. + * This workaround avoids the bug in QEMU versions older than 7.0.0. */ + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; +} + +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + volatile uint32_t ulDummy = 0UL; + + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). Artificially force an assert() + * to be triggered if configASSERT() is defined, then stop here so + * application writers can catch the error. */ + configASSERT( ulCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + * started to remove a compiler warning about the function being + * defined but never called. ulDummy is used purely to quieten other + * warnings about code appearing after this function is called - making + * ulDummy volatile makes the compiler think the function could return + * and therefore not output an 'unreachable code' warning for code that + * appears after it. */ + } +} + +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + + static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) + { + uint32_t ulRegionSize, ulReturnValue = 7UL; + + /* 256 is the smallest region size, 31 is the largest valid value for + * ulReturnValue. */ + for( ulRegionSize = 256UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) + { + if( ulActualSizeInBytes <= ulRegionSize ) + { + break; + } + else + { + ulReturnValue++; + } + } + + /* Shift the code by one before returning so it can be written directly + * into the the correct bit position of the attribute register. */ + return( ulReturnValue << 1UL ); + } + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ + { + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + extern uint32_t * __FLASH_segment_start__; + extern uint32_t * __FLASH_segment_end__; + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + + #else /* if defined( __ARMCC_VERSION ) */ + + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + extern uint32_t __FLASH_segment_start__[]; + extern uint32_t __FLASH_segment_end__[]; + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + + #endif /* defined( __ARMCC_VERSION ) */ + + /* Ensure that the MPU is present. */ + configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + + /* Check that the MPU is present. */ + if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) + { + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */ + ( portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ) | + ( portPRIVILEGED_FLASH_REGION ) ); + + portMPU_RASR_REG = ( ( portMPU_REGION_PRIV_RO_UNPRIV_NA ) | + ( ( configS_C_B_FLASH & portMPU_RASR_S_C_B_BITMASK ) << portMPU_RASR_S_C_B_LOCATION ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__ ) ) | + ( portMPU_RASR_REGION_ENABLE_BITMASK ) ); + + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RBAR_REG = ( ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ + ( portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ) | + ( portUNPRIVILEGED_FLASH_REGION ) ); + + portMPU_RASR_REG = ( ( portMPU_REGION_PRIV_RO_UNPRIV_RO ) | + ( ( configS_C_B_FLASH & portMPU_RASR_S_C_B_BITMASK ) << portMPU_RASR_S_C_B_LOCATION ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | + ( portMPU_RASR_REGION_ENABLE_BITMASK ) ); + + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RBAR_REG = ( ( uint32_t ) __privileged_sram_start__ ) | /* Base address. */ + ( portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ) | + ( portPRIVILEGED_RAM_REGION ); + + portMPU_RASR_REG = ( ( portMPU_REGION_PRIV_RW_UNPRIV_NA ) | + ( portMPU_REGION_EXECUTE_NEVER ) | + ( ( configS_C_B_SRAM & portMPU_RASR_S_C_B_BITMASK ) << portMPU_RASR_S_C_B_LOCATION ) | + prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_sram_end__ - ( uint32_t ) __privileged_sram_start__ ) | + ( portMPU_RASR_REGION_ENABLE_BITMASK ) ); + + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_CTRL_PRIV_BACKGROUND_ENABLE_BITMASK | + portMPU_CTRL_ENABLE_BITMASK ); + } + } + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ + +void vPortYield( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} + +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting++; + + /* Barriers are normally not required but do ensure the code is + * completely within the specified behaviour for the architecture. */ + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "isb" ); +} + +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */ +{ + configASSERT( ulCriticalNesting ); + ulCriticalNesting--; + + if( ulCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} + +/*-----------------------------------------------------------*/ + +void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulPreviousMask; + + ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); + + traceISR_ENTER(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + traceISR_EXIT_TO_SCHEDULER(); + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + else + { + traceISR_EXIT(); + } + } + + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); +} + +/*-----------------------------------------------------------*/ + +void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ +{ + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + + #else + + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + + #endif /* defined( __ARMCC_VERSION ) */ + + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + uint32_t ulPC; + uint8_t ucSVCNumber; + + /* Register are stored on the stack in the following order - R0, R1, R2, R3, + * R12, LR, PC, xPSR. */ + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; + ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; + + switch( ucSVCNumber ) + { + case portSVC_START_SCHEDULER: + /* Setup the context of the first task so that the first task starts + * executing. */ + vRestoreContextOfFirstTask(); + break; + + #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 ) */ + + #if ( configENABLE_MPU == 1 ) + + case portSVC_YIELD: + vPortYield(); + break; + + #endif /* configENABLE_MPU == 1 */ + + default: + /* Incorrect SVC call. */ + configASSERT( pdFALSE ); + } +} + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + void vSystemCallEnter( uint32_t * pulTaskStack, + uint32_t ulLR, + uint8_t ucSystemCallNumber ) /* PRIVILEGED_FUNCTION */ + { + extern TaskHandle_t pxCurrentTCB; + extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulSystemCallLocation, i; + /* 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 + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + + #else + + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + + /* Checks: + * 1. SVC is raised from the system call section (i.e. application is + * not raising SVC directly). + * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must be NULL as + * it is non-NULL only during the execution of a system call (i.e. + * between system call enter and exit). + * 3. System call is not for a kernel API disabled by the configuration + * in FreeRTOSConfig.h. + * 4. We do not need to check that ucSystemCallNumber is within range + * because the assembly SVC handler checks that before calling + * this function. + */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) && + ( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ) && + ( uxSystemCallImplementations[ ucSystemCallNumber ] != ( UBaseType_t ) 0 ) ) + { + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the Link Register before the SVC was raised. + * It contains the address of the caller of the System Call entry + * point (i.e. the caller of the MPU_). We need to restore it + * when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + + /* Start executing the system call upon returning from this handler. */ + pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + + /* Raise a request to exit from the system call upon finishing the + * system call. */ + pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile + ( + " .syntax unified \n" + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } + } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + void vRequestSystemCallExit( void ) /* __attribute__( ( naked ) ) PRIVILEGED_FUNCTION */ + { + __asm volatile ( "svc %0 \n" ::"i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" ); + } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + void vSystemCallExit( uint32_t * pulSystemCallStack, + uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ + { + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulSystemCallLocation, i; + /* 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 + * exported from linker scripts. */ + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + + #else + + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + + /* Checks: + * 1. SVC is raised from the privileged code (i.e. application is not + * raising SVC directly). This SVC is only raised from + * vRequestSystemCallExit which is in the privileged code section. + * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must not be NULL - + * this means that we previously entered a system call and the + * application is not attempting to exit without entering a system + * call. + */ + if( ( ulSystemCallLocation >= ( uint32_t ) __privileged_functions_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __privileged_functions_end__ ) && + ( pxMpuSettings->xSystemCallStackInfo.pulTaskStack != NULL ) ) + { + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Return to the caller of the System Call entry point (i.e. the + * caller of the MPU_). */ + pulTaskStack[ portOFFSET_TO_PC ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + + /* Ensure that LR has a valid value.*/ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile + ( + " .syntax unified \n" + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } + } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + + BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; + } + +#endif /* configENABLE_MPU == 1 */ + +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ + { + xMPUSettings->ulContext[ 0 ] = 0x04040404; /* r4. */ + xMPUSettings->ulContext[ 1 ] = 0x05050505; /* r5. */ + xMPUSettings->ulContext[ 2 ] = 0x06060606; /* r6. */ + xMPUSettings->ulContext[ 3 ] = 0x07070707; /* r7. */ + xMPUSettings->ulContext[ 4 ] = 0x08080808; /* r8. */ + xMPUSettings->ulContext[ 5 ] = 0x09090909; /* r9. */ + xMPUSettings->ulContext[ 6 ] = 0x10101010; /* r10. */ + xMPUSettings->ulContext[ 7 ] = 0x11111111; /* r11. */ + + xMPUSettings->ulContext[ 8 ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ 9 ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ 10 ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ 11 ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ 12 ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ 13 ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + xMPUSettings->ulContext[ 14 ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ 15 ] = portINITIAL_XPSR; /* xPSR. */ + + xMPUSettings->ulContext[ 16 ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ 17 ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ 17 ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + } + xMPUSettings->ulContext[ 18 ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ 19 ] ); + } + +#else /* configENABLE_MPU */ + + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ + { + /* Simulate the stack frame as it would be created by a context switch + * 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--; + *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 = portINITIAL_EXC_RETURN; + } + #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--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + } + #endif /* portPRELOAD_REGISTERS */ + + return pxTopOfStack; + } + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* An application can install FreeRTOS interrupt handlers in one of the + * following ways: + * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler + * for SVCall and PendSV interrupts respectively. + * 2. Indirect Routing - Install separate handlers for SVCall and PendSV + * interrupts and route program control from those handlers to + * SVC_Handler and PendSV_Handler functions. + * + * Applications that use Indirect Routing must set + * configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct + * routing, which is validated here when configCHECK_HANDLER_INSTALLATION + * is 1, should be preferred when possible. */ + #if ( configCHECK_HANDLER_INSTALLATION == 1 ) + { + const portISR_t * const pxVectorTable = portSCB_VTOR_REG; + + /* Validate that the application has correctly installed the FreeRTOS + * handlers for SVCall and PendSV interrupts. We do not check the + * installation of the SysTick handler because the application may + * choose to drive the RTOS tick using a timer other than the SysTick + * timer by overriding the weak function vPortSetupTimerInterrupt(). + * + * Assertion failures here indicate incorrect installation of the + * FreeRTOS handlers. For help installing the FreeRTOS handlers, see + * https://www.freertos.org/Why-FreeRTOS/FAQs. + * + * Systems with a configurable address for the interrupt vector table + * can also encounter assertion failures or even system faults here if + * VTOR is not set correctly to point to the application's vector table. */ + configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler ); + configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler ); + } + #endif /* configCHECK_HANDLER_INSTALLATION */ + + /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall + * the highest priority. */ + portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; + portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; + portNVIC_SHPR2_REG = 0; + + #if ( configENABLE_MPU == 1 ) + { + /* Setup the Memory Protection Unit (MPU). */ + prvSetupMPU(); + } + #endif /* configENABLE_MPU */ + + /* Start the timer that generates the tick ISR. Interrupts are disabled + * here already. */ + vPortSetupTimerInterrupt(); + + /* Initialize the critical nesting count ready for the first task. */ + ulCriticalNesting = 0; + + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + + /* Start the first task. */ + vStartFirstTask(); + + /* Should never get here as the tasks will now be executing. Call the task + * exit error function to prevent compiler warnings about a static function + * not being called in the case that the application writer overrides this + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimization does not remove the + * symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here. */ + return 0; +} + +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ +{ + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( ulCriticalNesting == 1000UL ); +} + +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + configSTACK_DEPTH_TYPE uxStackDepth ) + { + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __SRAM_segment_start__; + extern uint32_t * __SRAM_segment_end__; + extern uint32_t * __privileged_sram_start__; + extern uint32_t * __privileged_sram_end__; + + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __SRAM_segment_start__[]; + extern uint32_t __SRAM_segment_end__[]; + extern uint32_t __privileged_sram_start__[]; + extern uint32_t __privileged_sram_end__[]; + + #endif /* defined( __ARMCC_VERSION ) */ + + int32_t lIndex; + uint32_t ul; + + if( xRegions == NULL ) + { + /* No MPU regions are specified so allow access to all RAM. */ + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = + ( ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ + ( portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ) | + ( portSTACK_REGION ) ); /* Region number. */ + + xMPUSettings->xRegionsSettings[ 0 ].ulRASR = + ( ( portMPU_REGION_PRIV_RW_UNPRIV_RW ) | + ( portMPU_REGION_EXECUTE_NEVER ) | + ( ( configS_C_B_SRAM & portMPU_RASR_S_C_B_BITMASK ) << portMPU_RASR_S_C_B_LOCATION ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | + ( portMPU_RASR_REGION_ENABLE_BITMASK ) ); + + + /* Invalidate user configurable regions. */ + for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + xMPUSettings->xRegionsSettings[ ul ].ulRBAR = ( ( ul - 1UL ) | portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ); + xMPUSettings->xRegionsSettings[ ul ].ulRASR = 0UL; + } + } + else + { + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that the + * stack region has already been configured. */ + if( uxStackDepth > 0 ) + { + /* Define the region that allows access to the stack. */ + xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = + ( ( ( uint32_t ) pxBottomOfStack ) | + ( portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ) | + ( portSTACK_REGION ) ); /* Region number. */ + + xMPUSettings->xRegionsSettings[ 0 ].ulRASR = + ( ( portMPU_REGION_PRIV_RW_UNPRIV_RW ) | + ( portMPU_REGION_EXECUTE_NEVER ) | + ( prvGetMPURegionSizeSetting( uxStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( ( configS_C_B_SRAM & portMPU_RASR_S_C_B_BITMASK ) << portMPU_RASR_S_C_B_LOCATION ) | + ( portMPU_RASR_REGION_ENABLE_BITMASK ) ); + } + + lIndex = 0; + + for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) + { + /* Translate the generic region definition contained in + * xRegions into the CM0+ specific MPU settings that are then + * stored in xMPUSettings. */ + xMPUSettings->xRegionsSettings[ ul ].ulRBAR = + ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | + ( portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ) | + ( ul - 1UL ); /* Region number. */ + + xMPUSettings->xRegionsSettings[ ul ].ulRASR = + ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | + ( xRegions[ lIndex ].ulParameters ) | + ( portMPU_RASR_REGION_ENABLE_BITMASK ); + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegionsSettings[ ul ].ulRBAR = ( ( ul - 1UL ) | portMPU_RBAR_REGION_NUMBER_VALID_BITMASK ); + xMPUSettings->xRegionsSettings[ ul ].ulRASR = 0UL; + } + + lIndex++; + } + } +} + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + uint32_t ulRegionStart, ulRegionSize, ulRegionEnd; + uint32_t ulMPURegionAccessPermissions; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRASR & + portMPU_RASR_REGION_ENABLE_BITMASK ) == portMPU_RASR_REGION_ENABLE_BITMASK ) + { + ulRegionStart = portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ); + ulRegionSize = portEXTRACT_REGION_SIZE_FROM_RASR( xTaskMpuSettings->xRegionsSettings[ i ].ulRASR ); + ulRegionEnd = ulRegionStart + ulRegionSize; + + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + ulRegionStart, + ulRegionEnd ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + ulRegionStart, + ulRegionEnd ) ) + { + ulMPURegionAccessPermissions = xTaskMpuSettings->xRegionsSettings[ i ].ulRASR & + portMPU_RASR_AP_BITMASK; + + if( ulAccessRequested == tskMPU_READ_PERMISSION ) /* RO. */ + { + if( ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_UNPRIV_RO ) || + ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RO_UNPRIV_RO ) || + ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_UNPRIV_RW ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + else if( ( ulAccessRequested & tskMPU_WRITE_PERMISSION ) != 0UL ) /* W or RW. */ + { + if( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_UNPRIV_RW ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + } + } + + return xAccessGranted; + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ + +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsInsideInterrupt( void ) +{ + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. Interrupt Program + * Status Register (IPSR) holds the exception number of the currently-executing + * exception or zero for Thread mode.*/ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ + +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM0/portasm.c b/portable/GCC/ARM_CM0/portasm.c new file mode 100644 index 000000000..179a71546 --- /dev/null +++ b/portable/GCC/ARM_CM0/portasm.c @@ -0,0 +1,526 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION + * is defined correctly and privileged functions are placed in correct sections. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Portasm includes. */ +#include "portasm.h" + +/* System call numbers includes. */ +#include "mpu_syscall_numbers.h" + +/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the + * header files. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if ( configENABLE_MPU == 1 ) + + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ + { + __asm volatile + ( + " .extern pxCurrentTCB \n" + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " \n" + " ldr r3, =pxCurrentTCB \n" /* r3 = &pxCurrentTCB. */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " adds r0, #4 \n" /* r0 = Second item in the TCB which is xMPUSettings. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " ldr r1, =0xe000ed9c \n" /* r1 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000eda0 \n" /* r2 = 0xe000eda0 [Location of RASR]. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read first set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read second set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read third set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read fourth set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read fifth set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, =pxCurrentTCB \n" /* r2 = &pxCurrentTCB. */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " subs r1, #12 \n" + " ldmia r1!, {r2-r4} \n" /* r2 = original PSP, r3 = CONTROL, r4 = LR. */ + " subs r1, #12 \n" + " msr psp, r2 \n" + " msr control, r3 \n" + " mov lr, r4 \n" + " \n" + " restore_general_regs_first_task: \n" + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r1, #48 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r1, #16 \n" + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + ::"i" ( portSVC_START_SCHEDULER ) : "memory" + ); + } + +#else /* configENABLE_MPU */ + + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ + { + __asm volatile + ( + " .extern pxCurrentTCB \n" + " .syntax unified \n" + " \n" + " ldr r2, =pxCurrentTCB \n" /* r2 = &pxCurrentTCB. */ + " ldr r1, [r2] \n" /* r1 = pxCurrentTCB.*/ + " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + " \n" + " ldm r0!, {r2} \n" /* Read from stack - r2 = EXC_RETURN. */ + " movs r1, #2 \n" /* r1 = 2. */ + " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r2 \n" /* Finally, branch to EXC_RETURN. */ + " \n" + " .align 4 \n" + ); + } + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ + +BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n" /* r0 = CONTROL. */ + " movs r1, #1 \n" /* r1 = 1. */ + " tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */ + " beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */ + " movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ + " bx lr \n" /* Return. */ + " running_privileged: \n" + " movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ + " bx lr \n" /* Return. */ + " \n" + " .align 4 \n" + ::: "r0", "r1", "memory" + ); +} + +/*-----------------------------------------------------------*/ + +void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n" /* Read the CONTROL register. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear the bit 0. */ + " msr control, r0 \n" /* Write back the new CONTROL value. */ + " bx lr \n" /* Return to the caller. */ + ::: "r0", "r1", "memory" + ); +} + +/*-----------------------------------------------------------*/ + +void vResetPrivilege( void ) /* __attribute__ (( naked )) */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, control \n" /* r0 = CONTROL. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* r0 = r0 | r1. */ + " msr control, r0 \n" /* CONTROL = r0. */ + " bx lr \n" /* Return to the caller. */ + ::: "r0", "r1", "memory" + ); +} + +/*-----------------------------------------------------------*/ + +void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + /* Don't reset the MSP stack as is done on CM3/4 devices. The reason is that + * the Vector Table Offset Register (VTOR) is optional in CM0+ architecture + * and therefore, may not be available on all the devices. */ + __asm volatile + ( + " .syntax unified \n" + " cpsie i \n" /* Globally enable interrupts. */ + " dsb \n" + " isb \n" + " svc %0 \n" /* System call to start the first task. */ + " nop \n" + " \n" + " .align 4 \n" + ::"i" ( portSVC_START_SCHEDULER ) : "memory" + ); +} + +/*-----------------------------------------------------------*/ + +uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " mrs r0, PRIMASK \n" + " cpsid i \n" + " bx lr \n" + ::: "memory" + ); +} + +/*-----------------------------------------------------------*/ + +void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " msr PRIMASK, r0 \n" + " bx lr \n" + ::: "memory" + ); +} + +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ + { + __asm volatile + ( + " .extern pxCurrentTCB \n" + " .syntax unified \n" + " \n" + " ldr r2, =pxCurrentTCB \n" /* r2 = &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + " stmia r1!, {r4-r7} \n" /* Store r4-r7. */ + " mov r4, r8 \n" /* r4 = r8. */ + " mov r5, r9 \n" /* r5 = r9. */ + " mov r6, r10 \n" /* r6 = r10. */ + " mov r7, r11 \n" /* r7 = r11. */ + " stmia r1!, {r4-r7} \n" /* Store r8-r11. */ + " ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */ + " stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */ + " ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */ + " stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r2, psp \n" /* r2 = PSP. */ + " mrs r3, control \n" /* r3 = CONTROL. */ + " mov r4, lr \n" /* r4 = LR. */ + " stmia r1!, {r2-r4} \n" /* Store original PSP (after hardware has saved context), CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " \n" + " program_mpu: \n" + " \n" + " ldr r2, =pxCurrentTCB \n" /* r2 = &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " adds r0, #4 \n" /* r0 = Second item in the TCB which is xMPUSettings. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU */ + " \n" + " ldr r1, =0xe000ed9c \n" /* r1 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000eda0 \n" /* r2 = 0xe000eda0 [Location of RASR]. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read first set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read second set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read third set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read fourth set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldmia r0!, {r3-r4} \n" /* Read fifth set of RBAR/RASR registers from TCB. */ + " str r3, [r1] \n" /* Program RBAR. */ + " str r4, [r2] \n" /* Program RASR. */ + " \n" + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, =pxCurrentTCB \n" /* r2 = &pxCurrentTCB. */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " subs r1, #12 \n" + " ldmia r1!, {r2-r4} \n" /* r2 = original PSP, r3 = CONTROL, r4 = LR. */ + " subs r1, #12 \n" + " msr psp, r2 \n" + " msr control, r3 \n" + " mov lr, r4 \n" + " \n" + " restore_general_regs: \n" + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r1, #48 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r1, #16 \n" + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + ); + } + +#else /* configENABLE_MPU */ + + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ + { + __asm volatile + ( + " .extern pxCurrentTCB \n" + " .syntax unified \n" + " \n" + " mrs r0, psp \n" /* Read PSP in r0. */ + " ldr r2, =pxCurrentTCB \n" /* r2 = &( pxCurrentTCB ). */ + " ldr r1, [r2] \n" /* r1 = pxCurrentTCB. */ + " subs r0, r0, #36 \n" /* Make space for LR and the remaining registers on the stack. */ + " str r0, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ + " stmia r0!, {r3-r7} \n" /* Store on the stack - LR and low registers that are not automatically saved. */ + " mov r4, r8 \n" /* r4 = r8. */ + " mov r5, r9 \n" /* r5 = r9. */ + " mov r6, r10 \n" /* r6 = r10. */ + " mov r7, r11 \n" /* r7 = r11. */ + " stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */ + " \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " \n" + " ldr r2, =pxCurrentTCB \n" /* r2 = &( pxCurrentTCB ). */ + " ldr r1, [r2] \n" /* r1 = pxCurrentTCB. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + " \n" + " adds r0, r0, #20 \n" /* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " msr psp, r0 \n" /* Remember the new top of stack for the task. */ + " subs r0, r0, #36 \n" /* Move to the starting of the saved context. */ + " ldmia r0!, {r3-r7} \n" /* Read from stack - r3 = LR and r4-r7 restored. */ + " bx r3 \n" + " \n" + " .align 4 \n" + ); + } + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern vPortSVCHandler_C \n" + " .extern vSystemCallEnter \n" + " .extern vSystemCallExit \n" + " .extern pxCurrentTCB \n" + " \n" + " movs r0, #4 \n" + " mov r1, lr \n" + " tst r0, r1 \n" + " beq stack_on_msp \n" + " \n" + " stack_on_psp: \n" + " mrs r0, psp \n" + " b route_svc \n" + " \n" + " stack_on_msp: \n" + " mrs r0, msp \n" + " b route_svc \n" + " \n" + " route_svc: \n" + " ldr r3, [r0, #24] \n" + " subs r3, #2 \n" + " ldrb r2, [r3, #0] \n" + " ldr r3, =%0 \n" + " cmp r2, r3 \n" + " blt system_call_enter \n" + " ldr r3, =%1 \n" + " cmp r2, r3 \n" + " beq system_call_exit \n" + " ldr r3, =vPortSVCHandler_C \n" + " bx r3 \n" + " \n" + " system_call_enter: \n" + " push {lr} \n" + " bl vSystemCallEnter \n" + " pop {pc} \n" + " \n" + " system_call_exit: \n" + " push {lr} \n" + " bl vSystemCallExit \n" + " pop {pc} \n" + " \n" + " .align 4 \n" + " \n" + : /* No outputs. */ + : "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "r3", "memory" + ); + } + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern vPortSVCHandler_C \n" + " \n" + " movs r0, #4 \n" + " mov r1, lr \n" + " tst r0, r1 \n" + " beq stacking_used_msp \n" + " \n" + " stacking_used_psp: \n" + " mrs r0, psp \n" + " ldr r3, =vPortSVCHandler_C \n" + " bx r3 \n" + " \n" + " stacking_used_msp: \n" + " mrs r0, msp \n" + " ldr r3, =vPortSVCHandler_C \n" + " bx r3 \n" + " \n" + " .align 4 \n" + ); + } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM0/portasm.h b/portable/GCC/ARM_CM0/portasm.h new file mode 100644 index 000000000..346507531 --- /dev/null +++ b/portable/GCC/ARM_CM0/portasm.h @@ -0,0 +1,99 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef __PORT_ASM_H__ +#define __PORT_ASM_H__ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* MPU wrappers includes. */ +#include "mpu_wrappers.h" + +/** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ +void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ +BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + +/** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ +void vResetPrivilege( void ) __attribute__( ( naked ) ); + +/** + * @brief Starts the first task. + */ +void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Disables interrupts. + */ +uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief Enables interrupts. + */ +void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief PendSV Exception handler. + */ +void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +/** + * @brief SVC Handler. + */ +void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + +#endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index 3c55b5d0c..5acb2dcd2 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -26,7 +26,6 @@ * */ - #ifndef PORTMACRO_H #define PORTMACRO_H @@ -36,17 +35,25 @@ #endif /* *INDENT-ON* */ -/*----------------------------------------------------------- +/*------------------------------------------------------------------------------ * Port specific definitions. * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. * * These settings should not be altered. - *----------------------------------------------------------- + *------------------------------------------------------------------------------ */ -/* Type definitions. */ +#ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ + +/** + * @brief Type definitions. + */ #define portCHAR char #define portFLOAT float #define portDOUBLE double @@ -60,33 +67,223 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL -/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do - * not need to be guarded with a critical section. */ + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif /*-----------------------------------------------------------*/ -/* Architecture specifics. */ -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 8 -#define portDONT_DISCARD __attribute__( ( used ) ) +/** + * Architecture specifics. + */ +#define portARCH_NAME "Cortex-M0+" +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +#define portNOP() +#define portINLINE __inline +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) +#endif +#define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ +/** + * @brief Extern declarations. + */ +extern BaseType_t xPortIsInsideInterrupt( void ); + +extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; + +extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; +extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; + +extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; +extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; + +#if ( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +/** + * @brief MPU specific constants. + */ +#if ( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) +#else + #define portPRIVILEGE_BIT ( 0x0UL ) +#endif /* configENABLE_MPU */ + +/* Shareable (S), Cacheable (C) and Bufferable (B) bits for flash region. */ +#ifndef configS_C_B_FLASH + #define configS_C_B_FLASH ( 0x07UL ) +#endif + +/* Shareable (S), Cacheable (C) and Bufferable (B) bits for RAM region. */ +#ifndef configS_C_B_SRAM + #define configS_C_B_SRAM ( 0x07UL ) +#endif + +/* MPU regions. */ +#define portPRIVILEGED_RAM_REGION ( 7UL ) +#define portPRIVILEGED_FLASH_REGION ( 6UL ) +#define portUNPRIVILEGED_FLASH_REGION ( 5UL ) +#define portSTACK_REGION ( 4UL ) +#define portFIRST_CONFIGURABLE_REGION ( 0UL ) +#define portLAST_CONFIGURABLE_REGION ( 3UL ) +#define portNUM_CONFIGURABLE_REGIONS ( 4UL ) +#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1UL ) /* Plus one to make space for the stack region. */ + +/* MPU region sizes. This information is encoded in the SIZE bits of the MPU + * Region Attribute and Size Register (RASR). */ +#define portMPU_REGION_SIZE_256B ( 0x07UL << 1UL ) +#define portMPU_REGION_SIZE_512B ( 0x08UL << 1UL ) +#define portMPU_REGION_SIZE_1KB ( 0x09UL << 1UL ) +#define portMPU_REGION_SIZE_2KB ( 0x0AUL << 1UL ) +#define portMPU_REGION_SIZE_4KB ( 0x0BUL << 1UL ) +#define portMPU_REGION_SIZE_8KB ( 0x0CUL << 1UL ) +#define portMPU_REGION_SIZE_16KB ( 0x0DUL << 1UL ) +#define portMPU_REGION_SIZE_32KB ( 0x0EUL << 1UL ) +#define portMPU_REGION_SIZE_64KB ( 0x0FUL << 1UL ) +#define portMPU_REGION_SIZE_128KB ( 0x10UL << 1UL ) +#define portMPU_REGION_SIZE_256KB ( 0x11UL << 1UL ) +#define portMPU_REGION_SIZE_512KB ( 0x12UL << 1UL ) +#define portMPU_REGION_SIZE_1MB ( 0x13UL << 1UL ) +#define portMPU_REGION_SIZE_2MB ( 0x14UL << 1UL ) +#define portMPU_REGION_SIZE_4MB ( 0x15UL << 1UL ) +#define portMPU_REGION_SIZE_8MB ( 0x16UL << 1UL ) +#define portMPU_REGION_SIZE_16MB ( 0x17UL << 1UL ) +#define portMPU_REGION_SIZE_32MB ( 0x18UL << 1UL ) +#define portMPU_REGION_SIZE_64MB ( 0x19UL << 1UL ) +#define portMPU_REGION_SIZE_128MB ( 0x1AUL << 1UL ) +#define portMPU_REGION_SIZE_256MB ( 0x1BUL << 1UL ) +#define portMPU_REGION_SIZE_512MB ( 0x1CUL << 1UL ) +#define portMPU_REGION_SIZE_1GB ( 0x1DUL << 1UL ) +#define portMPU_REGION_SIZE_2GB ( 0x1EUL << 1UL ) +#define portMPU_REGION_SIZE_4GB ( 0x1FUL << 1UL ) + +/* MPU memory types. This information is encoded in the S ( Shareable), C + * (Cacheable) and B (Bufferable) bits of the MPU Region Attribute and Size + * Register (RASR). */ +#define portMPU_REGION_STRONGLY_ORDERED_SHAREABLE ( 0x0UL << 16UL ) /* S=NA, C=0, B=0. */ +#define portMPU_REGION_DEVICE_SHAREABLE ( 0x1UL << 16UL ) /* S=NA, C=0, B=1. */ +#define portMPU_REGION_NORMAL_OIWTNOWA_NONSHARED ( 0x2UL << 16UL ) /* S=0, C=1, B=0. */ +#define portMPU_REGION_NORMAL_OIWTNOWA_SHARED ( 0x6UL << 16UL ) /* S=1, C=1, B=0. */ +#define portMPU_REGION_NORMAL_OIWBNOWA_NONSHARED ( 0x3UL << 16UL ) /* S=0, C=1, B=1.*/ +#define portMPU_REGION_NORMAL_OIWBNOWA_SHARED ( 0x7UL << 16UL ) /* S=1, C=1, B=1.*/ + +/* MPU access permissions. This information is encoded in the AP and XN bits of + * the MPU Region Attribute and Size Register (RASR). */ +#define portMPU_REGION_PRIV_NA_UNPRIV_NA ( 0x0UL << 24UL ) +#define portMPU_REGION_PRIV_RW_UNPRIV_NA ( 0x1UL << 24UL ) +#define portMPU_REGION_PRIV_RW_UNPRIV_RO ( 0x2UL << 24UL ) +#define portMPU_REGION_PRIV_RW_UNPRIV_RW ( 0x3UL << 24UL ) +#define portMPU_REGION_PRIV_RO_UNPRIV_NA ( 0x5UL << 24UL ) +#define portMPU_REGION_PRIV_RO_UNPRIV_RO ( 0x6UL << 24UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x1UL << 28UL ) + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< MPU Region Base Address Register (RBAR) for the region. */ + uint32_t ulRASR; /**< MPU Region Attribute and Size Register (RASR) for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + + /* + * +----------+-----------------+---------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+---------------+-----+ + * + * <---------><----------------><---------------><----> + * 8 8 3 1 + */ + #define CONTEXT_SIZE 20 + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + /* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + + typedef struct MPU_SETTINGS + { + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ +#define portSVC_START_SCHEDULER 100 +#define portSVC_RAISE_PRIVILEGE 101 +#define portSVC_SYSTEM_CALL_EXIT 102 +#define portSVC_YIELD 103 +/*-----------------------------------------------------------*/ + +/** + * @brief Scheduler utilities. + */ +#if ( configENABLE_MPU == 1 ) + #define portYIELD() __asm volatile ( "svc %0" ::"i" ( portSVC_YIELD ) : "memory" ) + #define portYIELD_WITHIN_API() vPortYield() +#else + #define portYIELD() vPortYield() + #define portYIELD_WITHIN_API() vPortYield() +#endif -/* Scheduler utilities. */ -extern void vPortYield( void ); #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) -#define portYIELD() vPortYield() #define portEND_SWITCHING_ISR( xSwitchRequired ) \ do \ { \ @@ -103,66 +300,84 @@ extern void vPortYield( void ); #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ - -/* Critical section management. */ -extern void vPortEnterCritical( void ); -extern void vPortExitCritical( void ); -extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) ); -extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) ); - -#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) -#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) -#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) -#define portENTER_CRITICAL() vPortEnterCritical() -#define portEXIT_CRITICAL() vPortExitCritical() - +/** + * @brief Critical section management. + */ +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) +#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) +#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() /*-----------------------------------------------------------*/ -/* Tickless idle/low power functionality. */ +/** + * @brief Tickless idle/low power functionality. + */ #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /*-----------------------------------------------------------*/ -/* Task function macros as described on the FreeRTOS.org WEB site. */ +/** + * @brief Task function macros as described on the FreeRTOS.org website. + */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - -#define portNOP() - -#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) - - -#define portINLINE __inline - -#ifndef portFORCE_INLINE - #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) -#endif - /*-----------------------------------------------------------*/ -portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) -{ - uint32_t ulCurrentInterrupt; - BaseType_t xReturn; +#if ( configENABLE_MPU == 1 ) - /* Obtain the number of the currently executing interrupt. */ - __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() - if( ulCurrentInterrupt == 0 ) - { - xReturn = pdFALSE; - } - else - { - xReturn = pdTRUE; - } + /** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); - return xReturn; -} + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() +#else + + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() + +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +/** + * @brief Barriers. + */ +#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ /* *INDENT-OFF* */ diff --git a/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c index e67f3cbae..7a62caff0 100644 --- a/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -63,12 +63,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -93,12 +92,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -123,12 +121,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -153,12 +150,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -183,12 +179,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0, r1} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -219,12 +214,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -249,12 +243,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -279,12 +272,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -309,12 +301,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -337,12 +328,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -363,12 +353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -391,12 +380,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -421,12 +409,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -451,12 +438,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -481,12 +467,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -513,12 +498,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -543,12 +527,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -577,12 +560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -609,12 +591,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -643,12 +624,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -673,12 +653,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -703,12 +682,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -733,12 +711,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -763,12 +740,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -791,12 +767,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -819,12 +794,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -847,12 +821,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -877,12 +850,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -911,12 +883,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -943,12 +914,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -977,12 +947,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -1011,12 +980,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1037,12 +1005,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1063,12 +1030,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1093,12 +1059,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1123,12 +1088,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1151,12 +1115,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1179,12 +1142,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1211,12 +1173,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1241,12 +1202,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1273,12 +1233,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1305,12 +1264,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1337,12 +1295,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1367,12 +1324,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1397,12 +1353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1427,12 +1382,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1459,12 +1413,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1489,12 +1442,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1519,12 +1471,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1542,21 +1493,20 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1579,12 +1529,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1597,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1611,12 +1560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1641,12 +1589,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1671,12 +1618,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1701,12 +1647,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1731,12 +1676,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1746,121 +1690,133 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1875,22 +1831,21 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1907,241 +1862,264 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.c b/portable/GCC/ARM_CM23/non_secure/portasm.c index f8b37b691..978d35259 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23/non_secure/portasm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -56,11 +56,11 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -68,34 +68,34 @@ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -103,7 +103,7 @@ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" @@ -114,7 +114,7 @@ " msr psp, r3 \n" " msr control, r5 \n" " mov lr, r6 \n" - " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " \n" " restore_general_regs_first_task: \n" @@ -136,14 +136,6 @@ " restore_context_done_first_task: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xSecureContextConst2: .word xSecureContext \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -155,12 +147,12 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" + " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " movs r1, #2 \n" /* r1 = 2. */ " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ @@ -168,10 +160,6 @@ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " bx r3 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - "xSecureContextConst2: .word xSecureContext \n" ); } @@ -193,8 +181,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " running_privileged: \n" " movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "r1", "memory" ); } @@ -238,7 +224,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -247,9 +233,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -292,9 +275,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ " \n" @@ -337,11 +320,11 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " cpsie i \n" " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -349,34 +332,34 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -384,7 +367,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" @@ -395,7 +378,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr psp, r3 \n" " msr control, r5 \n" " mov lr, r6 \n" - " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " cbz r0, restore_ns_context \n" /* No secure context to restore. */ " \n" @@ -429,14 +412,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xSecureContextConst: .word xSecureContext \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ); } @@ -450,9 +425,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ " mrs r2, psp \n" /* Read PSP in r2. */ " \n" @@ -463,7 +438,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov lr, r3 \n" /* LR = r3. */ " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -473,7 +448,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " b select_next_task \n" " \n" " save_ns_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -491,16 +466,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " bl vTaskSwitchContext \n" " cpsie i \n" " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " mov lr, r4 \n" /* LR = r4. */ - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r3] \n" /* Restore the task's xSecureContext. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " push {r2, r4} \n" " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ @@ -522,10 +497,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " subs r2, r2, #32 \n" /* Go back to the low registers. */ " ldmia r2!, {r4-r7} \n" /* Restore the low registers that are not automatically restored. */ " bx lr \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - "xSecureContextConst: .word xSecureContext \n" ); } @@ -588,15 +559,12 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.h b/portable/GCC/ARM_CM23/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.h +++ b/portable/GCC/ARM_CM23/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM23/non_secure/portmacro.h b/portable/GCC/ARM_CM23/non_secure/portmacro.h index 33d522488..e81b89228 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.c +++ b/portable/GCC/ARM_CM23/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM23/secure/secure_context.h b/portable/GCC/ARM_CM23/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.h +++ b/portable/GCC/ARM_CM23/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM23/secure/secure_context_port.c b/portable/GCC/ARM_CM23/secure/secure_context_port.c index 2d9eeeaf8..32559ad04 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context_port.c +++ b/portable/GCC/ARM_CM23/secure/secure_context_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM23/secure/secure_heap.c b/portable/GCC/ARM_CM23/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/GCC/ARM_CM23/secure/secure_heap.c +++ b/portable/GCC/ARM_CM23/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/GCC/ARM_CM23/secure/secure_heap.h b/portable/GCC/ARM_CM23/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/GCC/ARM_CM23/secure/secure_heap.h +++ b/portable/GCC/ARM_CM23/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM23/secure/secure_init.c b/portable/GCC/ARM_CM23/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/GCC/ARM_CM23/secure/secure_init.c +++ b/portable/GCC/ARM_CM23/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM23/secure/secure_init.h b/portable/GCC/ARM_CM23/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/GCC/ARM_CM23/secure/secure_init.h +++ b/portable/GCC/ARM_CM23/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM23/secure/secure_port_macros.h b/portable/GCC/ARM_CM23/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/GCC/ARM_CM23/secure/secure_port_macros.h +++ b/portable/GCC/ARM_CM23/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c index e67f3cbae..7a62caff0 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -63,12 +63,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -93,12 +92,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -123,12 +121,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -153,12 +150,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -183,12 +179,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0, r1} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -219,12 +214,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -249,12 +243,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -279,12 +272,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -309,12 +301,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -337,12 +328,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -363,12 +353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -391,12 +380,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -421,12 +409,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -451,12 +438,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -481,12 +467,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -513,12 +498,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -543,12 +527,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -577,12 +560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -609,12 +591,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -643,12 +624,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -673,12 +653,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -703,12 +682,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -733,12 +711,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -763,12 +740,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -791,12 +767,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -819,12 +794,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -847,12 +821,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -877,12 +850,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -911,12 +883,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -943,12 +914,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -977,12 +947,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0, r1} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -1011,12 +980,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1037,12 +1005,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1063,12 +1030,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1093,12 +1059,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1123,12 +1088,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1151,12 +1115,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1179,12 +1142,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1211,12 +1173,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1241,12 +1202,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1273,12 +1233,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1305,12 +1264,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0, r1} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1337,12 +1295,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1367,12 +1324,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0, r1} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1397,12 +1353,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1427,12 +1382,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1459,12 +1413,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1489,12 +1442,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1519,12 +1471,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1542,21 +1493,20 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1579,12 +1529,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0, r1} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1597,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1611,12 +1560,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1641,12 +1589,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1671,12 +1618,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1701,12 +1647,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1731,12 +1676,11 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0, r1} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1746,121 +1690,133 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1875,22 +1831,21 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1907,241 +1862,264 @@ " mrs r0, control \n" " movs r1, #1 \n" " tst r0, r1 \n" + " pop {r0, r1} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0, r1} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0, r1} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0, r1} \n" - " mrs r0, control \n" - " movs r1, #1 \n" - " tst r0, r1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0, r1} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0, r1} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " pop {r0, r1} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c index 5fde8342e..d215f8f73 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -56,11 +56,11 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -68,34 +68,34 @@ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -103,7 +103,7 @@ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -137,13 +137,6 @@ " restore_context_done_first_task: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -155,7 +148,7 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" @@ -169,9 +162,6 @@ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " bx r2 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -193,8 +183,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " running_privileged: \n" " movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "r1", "memory" ); } @@ -238,7 +226,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -247,9 +235,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -290,7 +275,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ " mrs r2, psp \n" /* r2 = PSP. */ @@ -325,11 +310,11 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " cpsie i \n" " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ @@ -337,34 +322,34 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ " movs r3, #5 \n" /* r3 = 5. */ " str r3, [r1] \n" /* Program RNR = 5. */ " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ " movs r3, #6 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 6. */ " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ " movs r3, #7 \n" /* r3 = 6. */ " str r3, [r1] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " movs r3, #1 \n" /* r3 = 1. */ " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ @@ -372,7 +357,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -406,13 +391,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ); } @@ -425,7 +403,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .syntax unified \n" " \n" " mrs r0, psp \n" /* Read PSP in r0. */ - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -446,7 +424,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " bl vTaskSwitchContext \n" " cpsie i \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" @@ -463,9 +441,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ #endif " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ); } @@ -528,15 +503,12 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " tst r0, r1 \n" " beq stacking_used_msp \n" " mrs r0, psp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" " stacking_used_msp: \n" " mrs r0, msp \n" - " ldr r2, svchandler_address_const \n" + " ldr r2, =vPortSVCHandler_C \n" " bx r2 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h index 33d522488..e81b89228 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c index 8ce6fa6c4..f2a6a1e83 100644 --- a/portable/GCC/ARM_CM3/port.c +++ b/portable/GCC/ARM_CM3/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -228,8 +228,8 @@ static void prvTaskExitError( void ) void vPortSVCHandler( void ) { __asm volatile ( - " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ - " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r3, =pxCurrentTCB \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Get the pxCurrentTCB address. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ " ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ " msr psp, r0 \n" /* Restore the task stack pointer. */ @@ -239,8 +239,7 @@ void vPortSVCHandler( void ) " orr r14, #0xd \n" " bx r14 \n" " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" + " .ltorg \n" ); } /*-----------------------------------------------------------*/ @@ -269,7 +268,7 @@ static void prvPortStartFirstTask( void ) BaseType_t xPortStartScheduler( void ) { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -292,7 +291,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -462,7 +461,7 @@ void xPortPendSVHandler( void ) " mrs r0, psp \n" " isb \n" " \n" - " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r3, =pxCurrentTCB \n" /* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */ @@ -483,8 +482,7 @@ void xPortPendSVHandler( void ) " isb \n" " bx r14 \n" " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" + " .ltorg \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -801,7 +799,7 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/GCC/ARM_CM3/portmacro.h b/portable/GCC/ARM_CM3/portmacro.h index 5d91d2139..75dbcfa6c 100644 --- a/portable/GCC/ARM_CM3/portmacro.h +++ b/portable/GCC/ARM_CM3/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -171,7 +171,7 @@ extern void vPortExitCritical( void ); /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..33410a0c3 100644 --- a/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,130 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1771,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1801,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index 16c598ad7..0ebbe48a4 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,57 +54,65 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " \n" " restore_general_regs_first_task: \n" @@ -115,14 +125,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xSecureContextConst2: .word xSecureContext \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -134,25 +136,32 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" + " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n" /* Finally, branch to EXC_RETURN. */ - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - "xSecureContextConst2: .word xSecureContext \n" ); } @@ -171,8 +180,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -214,7 +221,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -224,9 +231,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -240,7 +244,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -274,9 +278,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ " \n" @@ -293,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -313,11 +315,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -325,57 +335,65 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " cbz r0, restore_ns_context \n" /* No secure context to restore. */ " \n" @@ -393,25 +411,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xSecureContextConst: .word xSecureContext \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -422,93 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " b select_next_task \n" - " \n" - " save_ns_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n" /* LR = r4. */ - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - "xSecureContextConst: .word xSecureContext \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -566,11 +582,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.h b/portable/GCC/ARM_CM33/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.h +++ b/portable/GCC/ARM_CM33/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM33/non_secure/portmacro.h b/portable/GCC/ARM_CM33/non_secure/portmacro.h index 227327ac8..2d435ca0b 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -57,6 +58,13 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.c +++ b/portable/GCC/ARM_CM33/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM33/secure/secure_context.h b/portable/GCC/ARM_CM33/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.h +++ b/portable/GCC/ARM_CM33/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM33/secure/secure_context_port.c b/portable/GCC/ARM_CM33/secure/secure_context_port.c index 13520870b..2d3d9439d 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context_port.c +++ b/portable/GCC/ARM_CM33/secure/secure_context_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM33/secure/secure_heap.c b/portable/GCC/ARM_CM33/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/GCC/ARM_CM33/secure/secure_heap.c +++ b/portable/GCC/ARM_CM33/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/GCC/ARM_CM33/secure/secure_heap.h b/portable/GCC/ARM_CM33/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/GCC/ARM_CM33/secure/secure_heap.h +++ b/portable/GCC/ARM_CM33/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM33/secure/secure_init.c b/portable/GCC/ARM_CM33/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/GCC/ARM_CM33/secure/secure_init.c +++ b/portable/GCC/ARM_CM33/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM33/secure/secure_init.h b/portable/GCC/ARM_CM33/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/GCC/ARM_CM33/secure/secure_init.h +++ b/portable/GCC/ARM_CM33/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM33/secure/secure_port_macros.h b/portable/GCC/ARM_CM33/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/GCC/ARM_CM33/secure/secure_port_macros.h +++ b/portable/GCC/ARM_CM33/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..4b984932d 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,129 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1770,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1800,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c index 76ba642a0..bc7bb6071 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,52 +54,60 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -113,13 +123,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -131,23 +134,30 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -166,8 +176,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -209,7 +217,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -219,9 +227,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -235,7 +240,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -267,22 +272,21 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -291,11 +295,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -303,52 +315,60 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -358,24 +378,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -390,46 +403,61 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -487,11 +515,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h index 227327ac8..2d435ca0b 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -57,6 +58,13 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..33410a0c3 100644 --- a/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,130 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1771,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1801,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c index 16c598ad7..0ebbe48a4 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,57 +54,65 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " \n" " restore_general_regs_first_task: \n" @@ -115,14 +125,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xSecureContextConst2: .word xSecureContext \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -134,25 +136,32 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" + " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n" /* Finally, branch to EXC_RETURN. */ - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - "xSecureContextConst2: .word xSecureContext \n" ); } @@ -171,8 +180,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -214,7 +221,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -224,9 +231,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -240,7 +244,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -274,9 +278,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ " \n" @@ -293,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -313,11 +315,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -325,57 +335,65 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " cbz r0, restore_ns_context \n" /* No secure context to restore. */ " \n" @@ -393,25 +411,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xSecureContextConst: .word xSecureContext \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -422,93 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " b select_next_task \n" - " \n" - " save_ns_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n" /* LR = r4. */ - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - "xSecureContextConst: .word xSecureContext \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -566,11 +582,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.h b/portable/GCC/ARM_CM35P/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.h +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacro.h b/portable/GCC/ARM_CM35P/non_secure/portmacro.h index 66fa2056d..b886287ac 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -57,6 +58,13 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.c b/portable/GCC/ARM_CM35P/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_context.c +++ b/portable/GCC/ARM_CM35P/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.h b/portable/GCC/ARM_CM35P/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_context.h +++ b/portable/GCC/ARM_CM35P/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM35P/secure/secure_context_port.c b/portable/GCC/ARM_CM35P/secure/secure_context_port.c index 13520870b..2d3d9439d 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_context_port.c +++ b/portable/GCC/ARM_CM35P/secure/secure_context_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM35P/secure/secure_heap.c b/portable/GCC/ARM_CM35P/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_heap.c +++ b/portable/GCC/ARM_CM35P/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/GCC/ARM_CM35P/secure/secure_heap.h b/portable/GCC/ARM_CM35P/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_heap.h +++ b/portable/GCC/ARM_CM35P/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM35P/secure/secure_init.c b/portable/GCC/ARM_CM35P/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_init.c +++ b/portable/GCC/ARM_CM35P/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM35P/secure/secure_init.h b/portable/GCC/ARM_CM35P/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_init.h +++ b/portable/GCC/ARM_CM35P/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM35P/secure/secure_port_macros.h b/portable/GCC/ARM_CM35P/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_port_macros.h +++ b/portable/GCC/ARM_CM35P/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..4b984932d 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,129 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1770,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1800,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c index 76ba642a0..bc7bb6071 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,52 +54,60 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -113,13 +123,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -131,23 +134,30 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -166,8 +176,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -209,7 +217,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -219,9 +227,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -235,7 +240,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -267,22 +272,21 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -291,11 +295,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -303,52 +315,60 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -358,24 +378,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -390,46 +403,61 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -487,11 +515,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h index 66fa2056d..b886287ac 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ @@ -57,6 +58,13 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c index 6b76b376c..428e6e84a 100644 --- a/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,133 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1774,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1804,264 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index d8c18325c..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 (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -264,14 +266,14 @@ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; * switches can only occur when uxCriticalNesting is zero. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; -#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) /* * This variable is set to pdTRUE when the scheduler is started. */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; -#endif +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure @@ -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 ]; } @@ -695,7 +703,7 @@ static void prvRestoreContextOfFirstTask( void ) " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ " \n" /*------------ Program MPU. ------------ */ - " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ " \n" @@ -716,7 +724,7 @@ static void prvRestoreContextOfFirstTask( void ) " dsb \n" /* Force memory writes before continuing. */ " \n" /*---------- Restore Context. ---------- */ - " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -732,8 +740,6 @@ static void prvRestoreContextOfFirstTask( void ) " bx lr \n" " \n" " .ltorg \n" /* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } /*-----------------------------------------------------------*/ @@ -744,7 +750,7 @@ static void prvRestoreContextOfFirstTask( void ) BaseType_t xPortStartScheduler( void ) { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -767,7 +773,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -878,11 +884,11 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; - #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Start the first task. */ __asm volatile ( @@ -988,7 +994,7 @@ void xPortPendSVHandler( void ) __asm volatile ( - " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " ldr r1, [r2] \n" /* r1 = Location where the context should be saved. */ " \n" @@ -1012,7 +1018,7 @@ void xPortPendSVHandler( void ) " msr basepri, r0 \n" " \n" /*------------ Program MPU. ------------ */ - " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ " \n" @@ -1033,7 +1039,7 @@ void xPortPendSVHandler( void ) " dsb \n" /* Force memory writes before continuing. */ " \n" /*---------- Restore Context. ---------- */ - " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -1047,8 +1053,6 @@ void xPortPendSVHandler( void ) " bx lr \n" " \n" " .ltorg \n" /* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -1095,12 +1099,28 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) static void prvSetupMPU( void ) { - extern uint32_t __privileged_functions_start__[]; - extern uint32_t __privileged_functions_end__[]; - extern uint32_t __FLASH_segment_start__[]; - extern uint32_t __FLASH_segment_end__[]; - extern uint32_t __privileged_data_start__[]; - extern uint32_t __privileged_data_end__[]; + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + extern uint32_t * __FLASH_segment_start__; + extern uint32_t * __FLASH_segment_end__; + extern uint32_t * __privileged_data_start__; + extern uint32_t * __privileged_data_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + extern uint32_t __FLASH_segment_start__[]; + extern uint32_t __FLASH_segment_end__[]; + extern uint32_t __privileged_data_start__[]; + extern uint32_t __privileged_data_end__[]; + #endif /* if defined( __ARMCC_VERSION ) */ + + /* Ensure that the device has the expected MPU type */ + configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); /* Check the expected MPU is present. */ if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) @@ -1191,8 +1211,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -1227,12 +1245,24 @@ void vPortSwitchToUserMode( void ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { - extern uint32_t __SRAM_segment_start__[]; - extern uint32_t __SRAM_segment_end__[]; - extern uint32_t __privileged_data_start__[]; - extern uint32_t __privileged_data_end__[]; + #if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __SRAM_segment_start__; + extern uint32_t * __SRAM_segment_end__; + extern uint32_t * __privileged_data_start__; + extern uint32_t * __privileged_data_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __SRAM_segment_start__[]; + extern uint32_t __SRAM_segment_end__[]; + extern uint32_t __privileged_data_start__[]; + extern uint32_t __privileged_data_end__[]; + #endif /* if defined( __ARMCC_VERSION ) */ + int32_t lIndex; uint32_t ul; @@ -1272,7 +1302,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = @@ -1283,12 +1313,12 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | - ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( prvGetMPURegionSizeSetting ( ( uint32_t ) ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) ) ) | ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | ( portMPU_REGION_ENABLE ); xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + - ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1UL ); xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); } @@ -1343,45 +1373,57 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ -BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, - uint32_t ulBufferLength, - uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) -{ - uint32_t i, ulBufferStartAddress, ulBufferEndAddress; - BaseType_t xAccessGranted = pdFALSE; - const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { - xAccessGranted = pdTRUE; - } - else - { - if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( xSchedulerRunning == pdFALSE ) { - ulBufferStartAddress = ( uint32_t ) pvBuffer; - ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); - - for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) { - if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) { - xAccessGranted = pdTRUE; - break; + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } } } } + + return xAccessGranted; } - return xAccessGranted; -} +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) @@ -1422,7 +1464,7 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/GCC/ARM_CM3_MPU/portmacro.h b/portable/GCC/ARM_CM3_MPU/portmacro.h index 5983c7912..a2e6883c0 100644 --- a/portable/GCC/ARM_CM3_MPU/portmacro.h +++ b/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -125,6 +125,14 @@ typedef struct MPU_REGION_SETTINGS #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/* + * +------------------------------+-------------------------------+-----+ + * | CONTROL, r4-r11, EXC_RETURN | PSP, r0-r3, r12, LR, PC, xPSR | | + * +------------------------------+-------------------------------+-----+ + * + * <-----------------------------><-------------------------------><----> + * 10 9 1 + */ #define MAX_CONTEXT_SIZE ( 20 ) /* Size of an Access Control List (ACL) entry in bits. */ @@ -247,7 +255,7 @@ extern void vPortExitCritical( void ); /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c index 3e5151bdc..e6b481b1d 100644 --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -34,7 +34,7 @@ #include "FreeRTOS.h" #include "task.h" -#ifndef __VFP_FP__ +#ifndef __ARM_FP #error This port can only be used when the project options are configured to enable hardware floating point support. #endif @@ -260,8 +260,8 @@ static void prvTaskExitError( void ) void vPortSVCHandler( void ) { __asm volatile ( - " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ - " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r3, =pxCurrentTCB \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Get the pxCurrentTCB address. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ " msr psp, r0 \n" /* Restore the task stack pointer. */ @@ -270,8 +270,7 @@ void vPortSVCHandler( void ) " msr basepri, r0 \n" " bx r14 \n" " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" + " .ltorg \n" ); } /*-----------------------------------------------------------*/ @@ -312,7 +311,7 @@ BaseType_t xPortStartScheduler( void ) configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -335,7 +334,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -511,7 +510,7 @@ void xPortPendSVHandler( void ) " mrs r0, psp \n" " isb \n" " \n" - " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r3, =pxCurrentTCB \n" /* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ @@ -552,8 +551,7 @@ void xPortPendSVHandler( void ) " \n" " bx r14 \n" " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" + " .ltorg \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -886,7 +884,7 @@ static void vPortEnableVFP( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/GCC/ARM_CM4F/portmacro.h b/portable/GCC/ARM_CM4F/portmacro.h index 40b2d03e9..0a91d7c92 100644 --- a/portable/GCC/ARM_CM4F/portmacro.h +++ b/portable/GCC/ARM_CM4F/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -174,7 +174,7 @@ extern void vPortExitCritical( void ); /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c index 6b76b376c..428e6e84a 100644 --- a/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,133 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1774,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1804,264 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 0775cfbf8..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 (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -40,7 +42,7 @@ #include "task.h" #include "mpu_syscall_numbers.h" -#ifndef __VFP_FP__ +#ifndef __ARM_FP #error This port can only be used when the project options are configured to enable hardware floating point support. #endif @@ -289,14 +291,14 @@ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; * switches can only occur when uxCriticalNesting is zero. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; -#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) /* * This variable is set to pdTRUE when the scheduler is started. */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; -#endif +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure @@ -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 ]; } @@ -761,7 +771,7 @@ static void prvRestoreContextOfFirstTask( void ) " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ " \n" /*------------ Program MPU. ------------ */ - " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ " \n" @@ -789,7 +799,7 @@ static void prvRestoreContextOfFirstTask( void ) " dsb \n" /* Force memory writes before continuing. */ " \n" /*---------- Restore Context. ---------- */ - " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -805,8 +815,6 @@ static void prvRestoreContextOfFirstTask( void ) " bx lr \n" " \n" " .ltorg \n" /* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB\n" ); } /*-----------------------------------------------------------*/ @@ -830,7 +838,7 @@ BaseType_t xPortStartScheduler( void ) #endif /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -853,7 +861,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -963,11 +971,11 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; - #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); @@ -1084,7 +1092,7 @@ void xPortPendSVHandler( void ) __asm volatile ( - " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " ldr r1, [r2] \n" /* r1 = Location where the context should be saved. */ " \n" @@ -1122,7 +1130,7 @@ void xPortPendSVHandler( void ) " msr basepri, r0 \n" " \n" /*------------ Program MPU. ------------ */ - " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ " \n" @@ -1150,7 +1158,7 @@ void xPortPendSVHandler( void ) " dsb \n" /* Force memory writes before continuing. */ " \n" /*---------- Restore Context. ---------- */ - " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r3, =pxCurrentTCB \n" /* r3 = =pxCurrentTCB. */ " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ " \n" @@ -1170,8 +1178,6 @@ void xPortPendSVHandler( void ) " bx lr \n" " \n" " .ltorg \n" /* Assemble the current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -1349,8 +1355,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -1385,7 +1389,7 @@ void vPortSwitchToUserMode( void ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { #if defined( __ARMCC_VERSION ) @@ -1442,7 +1446,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = @@ -1453,13 +1457,13 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | - ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( prvGetMPURegionSizeSetting( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + - ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1UL ); xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); } @@ -1514,45 +1518,57 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ -BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, - uint32_t ulBufferLength, - uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) -{ - uint32_t i, ulBufferStartAddress, ulBufferEndAddress; - BaseType_t xAccessGranted = pdFALSE; - const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { - xAccessGranted = pdTRUE; - } - else - { - if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( xSchedulerRunning == pdFALSE ) { - ulBufferStartAddress = ( uint32_t ) pvBuffer; - ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); - - for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) { - if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) { - xAccessGranted = pdTRUE; - break; + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } } } } + + return xAccessGranted; } - return xAccessGranted; -} +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ #if ( configASSERT_DEFINED == 1 ) @@ -1593,7 +1609,7 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/GCC/ARM_CM4_MPU/portmacro.h b/portable/GCC/ARM_CM4_MPU/portmacro.h index 4b941e6fa..581b09d5c 100644 --- a/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -98,7 +98,7 @@ typedef unsigned long UBaseType_t; #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -219,7 +219,16 @@ typedef struct MPU_REGION_SETTINGS #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -#define MAX_CONTEXT_SIZE ( 52 ) +/* + * +---------+---------------+-----------------+-----------------+-----+ + * | s16-s31 | s0-s15, FPSCR | CONTROL, r4-r11 | PSP, r0-r3, r12 | | + * | | | EXC_RETURN | LR, PC, xPSR | | + * +---------+---------------+-----------------+-----------------+-----+ + * + * <--------><---------------><----------------><----------------><----> + * 16 17 10 9 1 + */ +#define MAX_CONTEXT_SIZE ( 53 ) /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) @@ -341,7 +350,7 @@ extern void vPortExitCritical( void ); /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..33410a0c3 100644 --- a/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,130 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1771,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1801,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.c b/portable/GCC/ARM_CM55/non_secure/portasm.c index 16c598ad7..0ebbe48a4 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,57 +54,65 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " \n" " restore_general_regs_first_task: \n" @@ -115,14 +125,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xSecureContextConst2: .word xSecureContext \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -134,25 +136,32 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" + " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n" /* Finally, branch to EXC_RETURN. */ - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - "xSecureContextConst2: .word xSecureContext \n" ); } @@ -171,8 +180,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -214,7 +221,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -224,9 +231,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -240,7 +244,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -274,9 +278,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ " \n" @@ -293,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -313,11 +315,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -325,57 +335,65 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " cbz r0, restore_ns_context \n" /* No secure context to restore. */ " \n" @@ -393,25 +411,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xSecureContextConst: .word xSecureContext \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -422,93 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " b select_next_task \n" - " \n" - " save_ns_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n" /* LR = r4. */ - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - "xSecureContextConst: .word xSecureContext \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -566,11 +582,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.h b/portable/GCC/ARM_CM55/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.h +++ b/portable/GCC/ARM_CM55/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM55/non_secure/portmacro.h b/portable/GCC/ARM_CM55/non_secure/portmacro.h index 7b011b5b5..c6a179c52 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM55/secure/secure_context.c b/portable/GCC/ARM_CM55/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/GCC/ARM_CM55/secure/secure_context.c +++ b/portable/GCC/ARM_CM55/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM55/secure/secure_context.h b/portable/GCC/ARM_CM55/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/GCC/ARM_CM55/secure/secure_context.h +++ b/portable/GCC/ARM_CM55/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM55/secure/secure_context_port.c b/portable/GCC/ARM_CM55/secure/secure_context_port.c index 13520870b..2d3d9439d 100644 --- a/portable/GCC/ARM_CM55/secure/secure_context_port.c +++ b/portable/GCC/ARM_CM55/secure/secure_context_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM55/secure/secure_heap.c b/portable/GCC/ARM_CM55/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/GCC/ARM_CM55/secure/secure_heap.c +++ b/portable/GCC/ARM_CM55/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/GCC/ARM_CM55/secure/secure_heap.h b/portable/GCC/ARM_CM55/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/GCC/ARM_CM55/secure/secure_heap.h +++ b/portable/GCC/ARM_CM55/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM55/secure/secure_init.c b/portable/GCC/ARM_CM55/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/GCC/ARM_CM55/secure/secure_init.c +++ b/portable/GCC/ARM_CM55/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM55/secure/secure_init.h b/portable/GCC/ARM_CM55/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/GCC/ARM_CM55/secure/secure_init.h +++ b/portable/GCC/ARM_CM55/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM55/secure/secure_port_macros.h b/portable/GCC/ARM_CM55/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/GCC/ARM_CM55/secure/secure_port_macros.h +++ b/portable/GCC/ARM_CM55/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..4b984932d 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,129 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1770,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1800,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c index 76ba642a0..bc7bb6071 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,52 +54,60 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -113,13 +123,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -131,23 +134,30 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -166,8 +176,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -209,7 +217,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -219,9 +227,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -235,7 +240,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -267,22 +272,21 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -291,11 +295,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -303,52 +315,60 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -358,24 +378,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -390,46 +403,61 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -487,11 +515,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h index 7b011b5b5..c6a179c52 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c index 3070445ab..6586980f4 100644 --- a/portable/GCC/ARM_CM7/r0p1/port.c +++ b/portable/GCC/ARM_CM7/r0p1/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -34,7 +34,7 @@ #include "FreeRTOS.h" #include "task.h" -#ifndef __VFP_FP__ +#ifndef __ARM_FP #error This port can only be used when the project options are configured to enable hardware floating point support. #endif @@ -254,8 +254,8 @@ static void prvTaskExitError( void ) void vPortSVCHandler( void ) { __asm volatile ( - " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ - " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r3, =pxCurrentTCB \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Get the pxCurrentTCB address. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ " msr psp, r0 \n" /* Restore the task stack pointer. */ @@ -264,8 +264,7 @@ void vPortSVCHandler( void ) " msr basepri, r0 \n" " bx r14 \n" " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" + " .ltorg \n" ); } /*-----------------------------------------------------------*/ @@ -300,7 +299,7 @@ static void prvPortStartFirstTask( void ) BaseType_t xPortStartScheduler( void ) { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -323,7 +322,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -499,7 +498,7 @@ void xPortPendSVHandler( void ) " mrs r0, psp \n" " isb \n" " \n" - " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r3, =pxCurrentTCB \n" /* Get the location of the current TCB. */ " ldr r2, [r3] \n" " \n" " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ @@ -542,8 +541,7 @@ void xPortPendSVHandler( void ) " \n" " bx r14 \n" " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" + " .ltorg \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -876,7 +874,7 @@ static void vPortEnableVFP( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/GCC/ARM_CM7/r0p1/portmacro.h b/portable/GCC/ARM_CM7/r0p1/portmacro.h index aa2199c25..4bc490b98 100644 --- a/portable/GCC/ARM_CM7/r0p1/portmacro.h +++ b/portable/GCC/ARM_CM7/r0p1/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -171,7 +171,7 @@ extern void vPortExitCritical( void ); /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..33410a0c3 100644 --- a/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,130 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1771,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1801,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.c b/portable/GCC/ARM_CM85/non_secure/portasm.c index 16c598ad7..0ebbe48a4 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,57 +54,65 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " \n" " restore_general_regs_first_task: \n" @@ -115,14 +125,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xSecureContextConst2: .word xSecureContext \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -134,25 +136,32 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" + " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r3 \n" /* Finally, branch to EXC_RETURN. */ - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" - "xSecureContextConst2: .word xSecureContext \n" ); } @@ -171,8 +180,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -214,7 +221,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -224,9 +231,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -240,7 +244,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -274,9 +278,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ " \n" @@ -293,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -313,11 +315,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -325,57 +335,65 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" " msr control, r5 \n" - " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " str r0, [r4] \n" /* Restore xSecureContext. */ " cbz r0, restore_ns_context \n" /* No secure context to restore. */ " \n" @@ -393,25 +411,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xSecureContextConst: .word xSecureContext \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -422,93 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " b select_next_task \n" - " \n" - " save_ns_context: \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n" /* r1 = PSPLIM. */ - " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n" /* LR = r4. */ - " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" - "xSecureContextConst: .word xSecureContext \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -566,11 +582,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.h b/portable/GCC/ARM_CM85/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.h +++ b/portable/GCC/ARM_CM85/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM85/non_secure/portmacro.h b/portable/GCC/ARM_CM85/non_secure/portmacro.h index a6fda8a88..7e14f2696 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CM85/secure/secure_context.c b/portable/GCC/ARM_CM85/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/GCC/ARM_CM85/secure/secure_context.c +++ b/portable/GCC/ARM_CM85/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM85/secure/secure_context.h b/portable/GCC/ARM_CM85/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/GCC/ARM_CM85/secure/secure_context.h +++ b/portable/GCC/ARM_CM85/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM85/secure/secure_context_port.c b/portable/GCC/ARM_CM85/secure/secure_context_port.c index 13520870b..2d3d9439d 100644 --- a/portable/GCC/ARM_CM85/secure/secure_context_port.c +++ b/portable/GCC/ARM_CM85/secure/secure_context_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM85/secure/secure_heap.c b/portable/GCC/ARM_CM85/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/GCC/ARM_CM85/secure/secure_heap.c +++ b/portable/GCC/ARM_CM85/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/GCC/ARM_CM85/secure/secure_heap.h b/portable/GCC/ARM_CM85/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/GCC/ARM_CM85/secure/secure_heap.h +++ b/portable/GCC/ARM_CM85/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM85/secure/secure_init.c b/portable/GCC/ARM_CM85/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/GCC/ARM_CM85/secure/secure_init.c +++ b/portable/GCC/ARM_CM85/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM85/secure/secure_init.h b/portable/GCC/ARM_CM85/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/GCC/ARM_CM85/secure/secure_init.h +++ b/portable/GCC/ARM_CM85/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM85/secure/secure_port_macros.h b/portable/GCC/ARM_CM85/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/GCC/ARM_CM85/secure/secure_port_macros.h +++ b/portable/GCC/ARM_CM85/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c index 4cb310afd..4b984932d 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskDelayUntil_Unpriv \n" " MPU_xTaskDelayUntil_Priv: \n" - " pop {r0} \n" " b MPU_xTaskDelayUntilImpl \n" " MPU_xTaskDelayUntil_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskDelayUntil ) : "memory" @@ -91,12 +90,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskAbortDelay_Unpriv \n" " MPU_xTaskAbortDelay_Priv: \n" - " pop {r0} \n" " b MPU_xTaskAbortDelayImpl \n" " MPU_xTaskAbortDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskAbortDelay ) : "memory" @@ -120,12 +118,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskDelay_Unpriv \n" " MPU_vTaskDelay_Priv: \n" - " pop {r0} \n" " b MPU_vTaskDelayImpl \n" " MPU_vTaskDelay_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskDelay ) : "memory" @@ -149,12 +146,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskPriorityGet_Unpriv \n" " MPU_uxTaskPriorityGet_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskPriorityGetImpl \n" " MPU_uxTaskPriorityGet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskPriorityGet ) : "memory" @@ -178,12 +174,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_eTaskGetState_Unpriv \n" " MPU_eTaskGetState_Priv: \n" - " pop {r0} \n" " b MPU_eTaskGetStateImpl \n" " MPU_eTaskGetState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_eTaskGetState ) : "memory" @@ -213,12 +208,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskGetInfo_Unpriv \n" " MPU_vTaskGetInfo_Priv: \n" - " pop {r0} \n" " b MPU_vTaskGetInfoImpl \n" " MPU_vTaskGetInfo_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskGetInfo ) : "memory" @@ -242,12 +236,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" " MPU_xTaskGetIdleTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetIdleTaskHandleImpl \n" " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetIdleTaskHandle ) : "memory" @@ -271,12 +264,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSuspend_Unpriv \n" " MPU_vTaskSuspend_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSuspendImpl \n" " MPU_vTaskSuspend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSuspend ) : "memory" @@ -300,12 +292,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskResume_Unpriv \n" " MPU_vTaskResume_Priv: \n" - " pop {r0} \n" " b MPU_vTaskResumeImpl \n" " MPU_vTaskResume_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskResume ) : "memory" @@ -327,12 +318,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetTickCount_Unpriv \n" " MPU_xTaskGetTickCount_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetTickCountImpl \n" " MPU_xTaskGetTickCount_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetTickCount ) : "memory" @@ -352,12 +342,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" " MPU_uxTaskGetNumberOfTasks_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetNumberOfTasksImpl \n" " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetNumberOfTasks ) : "memory" @@ -379,12 +368,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" " MPU_ulTaskGetRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimeCounterImpl \n" " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimeCounter ) : "memory" @@ -408,12 +396,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" " MPU_ulTaskGetRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetRunTimePercentImpl \n" " MPU_ulTaskGetRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetRunTimePercent ) : "memory" @@ -437,12 +424,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimePercentImpl \n" " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimePercent ) : "memory" @@ -466,12 +452,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter ) : "memory" @@ -497,12 +482,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" " MPU_vTaskSetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetApplicationTaskTagImpl \n" " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetApplicationTaskTag ) : "memory" @@ -526,12 +510,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" " MPU_xTaskGetApplicationTaskTag_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetApplicationTaskTagImpl \n" " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetApplicationTaskTag ) : "memory" @@ -559,12 +542,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer ) : "memory" @@ -590,12 +572,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" - " pop {r0} \n" " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer ) : "memory" @@ -623,12 +604,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetSystemState_Unpriv \n" " MPU_uxTaskGetSystemState_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetSystemStateImpl \n" " MPU_uxTaskGetSystemState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetSystemState ) : "memory" @@ -652,12 +632,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMarkImpl \n" " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark ) : "memory" @@ -681,12 +660,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" - " pop {r0} \n" " b MPU_uxTaskGetStackHighWaterMark2Impl \n" " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 ) : "memory" @@ -710,12 +688,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" " MPU_xTaskGetCurrentTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetCurrentTaskHandleImpl \n" " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetCurrentTaskHandle ) : "memory" @@ -739,12 +716,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGetSchedulerState_Unpriv \n" " MPU_xTaskGetSchedulerState_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGetSchedulerStateImpl \n" " MPU_xTaskGetSchedulerState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGetSchedulerState ) : "memory" @@ -766,12 +742,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTaskSetTimeOutState_Unpriv \n" " MPU_vTaskSetTimeOutState_Priv: \n" - " pop {r0} \n" " b MPU_vTaskSetTimeOutStateImpl \n" " MPU_vTaskSetTimeOutState_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTaskSetTimeOutState ) : "memory" @@ -793,12 +768,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskCheckForTimeOut_Unpriv \n" " MPU_xTaskCheckForTimeOut_Priv: \n" - " pop {r0} \n" " b MPU_xTaskCheckForTimeOutImpl \n" " MPU_xTaskCheckForTimeOut_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskCheckForTimeOut ) : "memory" @@ -820,12 +794,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotify_Unpriv \n" " MPU_xTaskGenericNotify_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyImpl \n" " MPU_xTaskGenericNotify_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotify ) : "memory" @@ -849,12 +822,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyWait_Unpriv \n" " MPU_xTaskGenericNotifyWait_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyWaitImpl \n" " MPU_xTaskGenericNotifyWait_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyWait ) : "memory" @@ -882,12 +854,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" " MPU_ulTaskGenericNotifyTake_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyTakeImpl \n" " MPU_ulTaskGenericNotifyTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyTake ) : "memory" @@ -913,12 +884,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" " MPU_xTaskGenericNotifyStateClear_Priv: \n" - " pop {r0} \n" " b MPU_xTaskGenericNotifyStateClearImpl \n" " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTaskGenericNotifyStateClear ) : "memory" @@ -946,12 +916,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" " MPU_ulTaskGenericNotifyValueClear_Priv: \n" - " pop {r0} \n" " b MPU_ulTaskGenericNotifyValueClearImpl \n" " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_ulTaskGenericNotifyValueClear ) : "memory" @@ -979,12 +948,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGenericSend_Unpriv \n" " MPU_xQueueGenericSend_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGenericSendImpl \n" " MPU_xQueueGenericSend_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGenericSend ) : "memory" @@ -1004,12 +972,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueMessagesWaiting_Unpriv \n" " MPU_uxQueueMessagesWaiting_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueMessagesWaitingImpl \n" " MPU_uxQueueMessagesWaiting_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueMessagesWaiting ) : "memory" @@ -1029,12 +996,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxQueueSpacesAvailable_Unpriv \n" " MPU_uxQueueSpacesAvailable_Priv: \n" - " pop {r0} \n" " b MPU_uxQueueSpacesAvailableImpl \n" " MPU_uxQueueSpacesAvailable_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxQueueSpacesAvailable ) : "memory" @@ -1058,12 +1024,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueReceive_Unpriv \n" " MPU_xQueueReceive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueReceiveImpl \n" " MPU_xQueueReceive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueReceive ) : "memory" @@ -1087,12 +1052,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueuePeek_Unpriv \n" " MPU_xQueuePeek_Priv: \n" - " pop {r0} \n" " b MPU_xQueuePeekImpl \n" " MPU_xQueuePeek_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueuePeek ) : "memory" @@ -1114,12 +1078,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSemaphoreTake_Unpriv \n" " MPU_xQueueSemaphoreTake_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSemaphoreTakeImpl \n" " MPU_xQueueSemaphoreTake_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSemaphoreTake ) : "memory" @@ -1141,12 +1104,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGetMutexHolder_Unpriv \n" " MPU_xQueueGetMutexHolder_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGetMutexHolderImpl \n" " MPU_xQueueGetMutexHolder_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGetMutexHolder ) : "memory" @@ -1172,12 +1134,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" " MPU_xQueueTakeMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueTakeMutexRecursiveImpl \n" " MPU_xQueueTakeMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueTakeMutexRecursive ) : "memory" @@ -1201,12 +1162,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" " MPU_xQueueGiveMutexRecursive_Priv: \n" - " pop {r0} \n" " b MPU_xQueueGiveMutexRecursiveImpl \n" " MPU_xQueueGiveMutexRecursive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueGiveMutexRecursive ) : "memory" @@ -1232,12 +1192,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueSelectFromSet_Unpriv \n" " MPU_xQueueSelectFromSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueSelectFromSetImpl \n" " MPU_xQueueSelectFromSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueSelectFromSet ) : "memory" @@ -1263,12 +1222,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xQueueAddToSet_Unpriv \n" " MPU_xQueueAddToSet_Priv: \n" - " pop {r0} \n" " b MPU_xQueueAddToSetImpl \n" " MPU_xQueueAddToSet_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xQueueAddToSet ) : "memory" @@ -1294,12 +1252,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueAddToRegistry_Unpriv \n" " MPU_vQueueAddToRegistry_Priv: \n" - " pop {r0} \n" " b MPU_vQueueAddToRegistryImpl \n" " MPU_vQueueAddToRegistry_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueAddToRegistry ) : "memory" @@ -1323,12 +1280,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vQueueUnregisterQueue_Unpriv \n" " MPU_vQueueUnregisterQueue_Priv: \n" - " pop {r0} \n" " b MPU_vQueueUnregisterQueueImpl \n" " MPU_vQueueUnregisterQueue_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vQueueUnregisterQueue ) : "memory" @@ -1352,12 +1308,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcQueueGetName_Unpriv \n" " MPU_pcQueueGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcQueueGetNameImpl \n" " MPU_pcQueueGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcQueueGetName ) : "memory" @@ -1381,12 +1336,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pvTimerGetTimerID_Unpriv \n" " MPU_pvTimerGetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_pvTimerGetTimerIDImpl \n" " MPU_pvTimerGetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pvTimerGetTimerID ) : "memory" @@ -1412,12 +1366,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetTimerID_Unpriv \n" " MPU_vTimerSetTimerID_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetTimerIDImpl \n" " MPU_vTimerSetTimerID_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetTimerID ) : "memory" @@ -1441,12 +1394,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerIsTimerActive_Unpriv \n" " MPU_xTimerIsTimerActive_Priv: \n" - " pop {r0} \n" " b MPU_xTimerIsTimerActiveImpl \n" " MPU_xTimerIsTimerActive_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerIsTimerActive ) : "memory" @@ -1470,12 +1422,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle ) : "memory" @@ -1493,20 +1444,19 @@ { __asm volatile ( - " .syntax unified \n" - " .extern MPU_xTimerGenericCommandFromTaskImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" - " MPU_xTimerGenericCommandFromTask_Priv: \n" - " pop {r0} \n" - " b MPU_xTimerGenericCommandFromTaskImpl \n" - " MPU_xTimerGenericCommandFromTask_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandFromTaskImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xTimerGenericCommandFromTask_Unpriv \n" + " MPU_xTimerGenericCommandFromTask_Priv: \n" + " b MPU_xTimerGenericCommandFromTaskImpl \n" + " MPU_xTimerGenericCommandFromTask_Unpriv: \n" + " svc %0 \n" + " \n" : : "i" ( SYSTEM_CALL_xTimerGenericCommandFromTask ) : "memory" ); } @@ -1528,12 +1478,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_pcTimerGetName_Unpriv \n" " MPU_pcTimerGetName_Priv: \n" - " pop {r0} \n" " b MPU_pcTimerGetNameImpl \n" " MPU_pcTimerGetName_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_pcTimerGetName ) : "memory" @@ -1546,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( @@ -1559,12 +1508,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vTimerSetReloadMode_Unpriv \n" " MPU_vTimerSetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_vTimerSetReloadModeImpl \n" " MPU_vTimerSetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vTimerSetReloadMode ) : "memory" @@ -1588,12 +1536,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetReloadMode_Unpriv \n" " MPU_xTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetReloadModeImpl \n" " MPU_xTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetReloadMode ) : "memory" @@ -1617,12 +1564,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxTimerGetReloadMode_Unpriv \n" " MPU_uxTimerGetReloadMode_Priv: \n" - " pop {r0} \n" " b MPU_uxTimerGetReloadModeImpl \n" " MPU_uxTimerGetReloadMode_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxTimerGetReloadMode ) : "memory" @@ -1646,12 +1592,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetPeriod_Unpriv \n" " MPU_xTimerGetPeriod_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetPeriodImpl \n" " MPU_xTimerGetPeriod_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetPeriod ) : "memory" @@ -1675,12 +1620,11 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_xTimerGetExpiryTime_Unpriv \n" " MPU_xTimerGetExpiryTime_Priv: \n" - " pop {r0} \n" " b MPU_xTimerGetExpiryTimeImpl \n" " MPU_xTimerGetExpiryTime_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_xTimerGetExpiryTime ) : "memory" @@ -1690,117 +1634,129 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupWaitBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupWaitBits_Unpriv \n" - " MPU_xEventGroupWaitBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupWaitBitsImpl \n" - " MPU_xEventGroupWaitBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupWaitBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupClearBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupClearBits_Unpriv \n" - " MPU_xEventGroupClearBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupClearBitsImpl \n" - " MPU_xEventGroupClearBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupClearBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSetBitsImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSetBits_Unpriv \n" - " MPU_xEventGroupSetBits_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSetBitsImpl \n" - " MPU_xEventGroupSetBits_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSetBits ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_EVENT_GROUPS == 1 ) - EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xEventGroupSyncImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xEventGroupSync_Unpriv \n" - " MPU_xEventGroupSync_Priv: \n" - " pop {r0} \n" - " b MPU_xEventGroupSyncImpl \n" - " MPU_xEventGroupSync_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" - ); - } + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xEventGroupSync ) : "memory" + ); + } + + #endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1814,22 +1770,21 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_uxEventGroupGetNumber_Unpriv \n" " MPU_uxEventGroupGetNumber_Priv: \n" - " pop {r0} \n" " b MPU_uxEventGroupGetNumberImpl \n" " MPU_uxEventGroupGetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_uxEventGroupGetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -1845,233 +1800,256 @@ " push {r0} \n" " mrs r0, control \n" " tst r0, #1 \n" + " pop {r0} \n" " bne MPU_vEventGroupSetNumber_Unpriv \n" " MPU_vEventGroupSetNumber_Priv: \n" - " pop {r0} \n" " b MPU_vEventGroupSetNumberImpl \n" " MPU_vEventGroupSetNumber_Unpriv: \n" - " pop {r0} \n" " svc %0 \n" " \n" : : "i" ( SYSTEM_CALL_vEventGroupSetNumber ) : "memory" ); } - #endif /*( configUSE_TRACE_FACILITY == 1 )*/ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSendImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSend_Unpriv \n" - " MPU_xStreamBufferSend_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSendImpl \n" - " MPU_xStreamBufferSend_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" - ); - } + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSend ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferReceiveImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferReceive_Unpriv \n" - " MPU_xStreamBufferReceive_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferReceiveImpl \n" - " MPU_xStreamBufferReceive_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" - ); - } + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferReceive ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsFullImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsFull_Unpriv \n" - " MPU_xStreamBufferIsFull_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsFullImpl \n" - " MPU_xStreamBufferIsFull_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsFull ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferIsEmptyImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferIsEmpty_Unpriv \n" - " MPU_xStreamBufferIsEmpty_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferIsEmptyImpl \n" - " MPU_xStreamBufferIsEmpty_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferIsEmpty ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSpacesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" - " MPU_xStreamBufferSpacesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSpacesAvailableImpl \n" - " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSpacesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferBytesAvailableImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" - " MPU_xStreamBufferBytesAvailable_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferBytesAvailableImpl \n" - " MPU_xStreamBufferBytesAvailable_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" - ); - } + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferBytesAvailable ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" - " MPU_xStreamBufferSetTriggerLevel_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferSetTriggerLevelImpl \n" - " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" - ); - } + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferSetTriggerLevel ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #if ( configUSE_STREAM_BUFFERS == 1 ) - size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ - { - __asm volatile - ( - " .syntax unified \n" - " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " \n" - " push {r0} \n" - " mrs r0, control \n" - " tst r0, #1 \n" - " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" - " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" - " pop {r0} \n" - " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" - " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" - " pop {r0} \n" - " svc %0 \n" - " \n" - : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" - ); - } + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + { + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " pop {r0} \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " svc %0 \n" + " \n" + : : "i" ( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes ) : "memory" + ); + } + + #endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c index 76ba642a0..bc7bb6071 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -52,52 +54,60 @@ " .syntax unified \n" " \n" " program_mpu_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context_first_task: \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -113,13 +123,6 @@ " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst2: .word pxCurrentTCB \n" - " xMPUCTRLConst2: .word 0xe000ed94 \n" - " xMAIR0Const2: .word 0xe000edc0 \n" - " xRNRConst2: .word 0xe000ed98 \n" - " xRBARConst2: .word 0xe000ed9c \n" ); } @@ -131,23 +134,30 @@ ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" " mov r0, #0 \n" " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ " bx r2 \n" /* Finally, branch to EXC_RETURN. */ - " \n" - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -166,8 +176,6 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ " movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ " moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ " bx lr \n" /* Return. */ - " \n" - " .align 4 \n" ::: "r0", "memory" ); } @@ -209,7 +217,7 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ ( " .syntax unified \n" " \n" - " ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */ " ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */ " msr msp, r0 \n" /* Set the MSP back to the start of the stack. */ @@ -219,9 +227,6 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " isb \n" " svc %0 \n" /* System call to start the first task. */ " nop \n" - " \n" - " .align 4 \n" - "xVTORConst: .word 0xe000ed08 \n" ::"i" ( portSVC_START_SCHEDULER ) : "memory" ); } @@ -235,7 +240,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -267,22 +272,21 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att ( " .syntax unified \n" " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -291,11 +295,19 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -303,52 +315,60 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " msr basepri, r0 \n" /* Enable interrupts. */ " \n" " program_mpu: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ " \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */ - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ " str r2, [r1] \n" /* Disable MPU. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ - " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r1, [r2] \n" /* Program MAIR0. */ " \n" " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ - " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ - " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " \n" " movs r3, #4 \n" /* r3 = 4. */ " str r3, [r1] \n" /* Program RNR = 4. */ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" - " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ " str r2, [r1] \n" /* Enable MPU. */ " dsb \n" /* Force memory writes before continuing. */ " \n" " restore_context: \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -358,24 +378,17 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ " bx lr \n" - " \n" - " .align 4 \n" - " pxCurrentTCBConst: .word pxCurrentTCB \n" - " xMPUCTRLConst: .word 0xe000ed94 \n" - " xMAIR0Const: .word 0xe000edc0 \n" - " xRNRConst: .word 0xe000ed98 \n" - " xRBARConst: .word 0xe000ed9c \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -390,46 +403,61 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */ " \n" - " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ " bx r3 \n" - " \n" - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -487,11 +515,8 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" - " ldr r1, svchandler_address_const \n" + " ldr r1, =vPortSVCHandler_C \n" " bx r1 \n" - " \n" - " .align 4 \n" - "svchandler_address_const: .word vPortSVCHandler_C \n" ); } diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h index a6fda8a88..7e14f2696 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/GCC/ARM_CR5/port.c b/portable/GCC/ARM_CR5/port.c index 323ea916d..72658e8d7 100644 --- a/portable/GCC/ARM_CR5/port.c +++ b/portable/GCC/ARM_CR5/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CR5/portASM.S b/portable/GCC/ARM_CR5/portASM.S index c331057d6..3c39ef1b6 100644 --- a/portable/GCC/ARM_CR5/portASM.S +++ b/portable/GCC/ARM_CR5/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -76,8 +76,8 @@ /* Save the floating point context, if any. */ FMRXNE R1, FPSCR - VPUSHNE {D0-D15} PUSHNE {R1} + VPUSHNE {D0-D15} /* Save ulPortTaskHasFPUContext itself. */ PUSH {R3} @@ -110,8 +110,8 @@ CMP R1, #0 /* Restore the floating point context, if any. */ - POPNE {R0} VPOPNE {D0-D15} + POPNE {R0} VMSRNE FPSCR, R0 #endif /* __ARM_FP */ @@ -147,8 +147,15 @@ FreeRTOS_SWI_Handler: /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT + + /* Ensure bit 2 of the stack pointer is clear. */ + MOV r2, sp + AND r2, r2, #4 + SUB sp, sp, r2 + LDR R0, vTaskSwitchContextConst BLX R0 + portRESTORE_CONTEXT @@ -242,7 +249,7 @@ exit_without_switch: MOVS PC, LR switch_before_exit: - /* A context swtich is to be performed. Clear the context switch pending + /* A context switch is to be performed. Clear the context switch pending flag. */ MOV r0, #0 STR r0, [r1] @@ -256,6 +263,11 @@ switch_before_exit: POP {LR} portSAVE_CONTEXT + /* Ensure bit 2 of the stack pointer is clear. */ + MOV r2, sp + AND r2, r2, #4 + SUB sp, sp, r2 + /* Call the function that selects the new task to execute. vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD instructions, or 8 byte aligned stack allocated data. LR does not need diff --git a/portable/GCC/ARM_CR5/portmacro.h b/portable/GCC/ARM_CR5/portmacro.h index ff7337d15..35336e569 100644 --- a/portable/GCC/ARM_CR5/portmacro.h +++ b/portable/GCC/ARM_CR5/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -163,7 +163,7 @@ void FreeRTOS_Tick_Handler( void ); #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ diff --git a/portable/GCC/ARM_CR82/README.md b/portable/GCC/ARM_CR82/README.md new file mode 100644 index 000000000..6a3003918 --- /dev/null +++ b/portable/GCC/ARM_CR82/README.md @@ -0,0 +1,42 @@ +# Arm Cortex-R82 FreeRTOS Kernel Port + +# Overview + +- This directory contains the FreeRTOS Kernel port for Arm Cortex-R82 based on Armv8-R AArch64 architecture. +- It provides the portable layer required by the kernel to run on this architecture. + +# Supported toolchains + +The port is supported and tested on the following toolchains: + + * Arm Compiler for Embedded v6.23 (armclang). + * Arm GNU toolchain v14.2. + +# Cache Coherency + +- This port assumes the hardware or model is fully cache coherent. +- The port does not perform cache maintenance for shared buffers. +- If your hardware or model doesn't support full cache coherency, you must handle cache clean/invalidate operations, memory attributes, and any additional barriers in your BSP/application (especially around shared-memory regions). + +# SMP Multicore Bring-up + +For SMP systems using this port, the application only needs to start the scheduler on the primary core and issue an SVC from each secondary core once they are online. The kernel coordinates the rest and ensures all cores are properly managed. + +- Developer-facing summary: call `vTaskStartScheduler()` on the primary core; each secondary core, in its **reset handler**, performs its local init and then issues an SVC (immediate value `106`) to hand off to the kernel. The port will bring all cores under the scheduler. + +Primary core flow: + +1. Perform core-specific and shared initialization (e.g., set EL1 stack pointer, zero-initialize `.bss`). +2. Jump to `main()`, create user tasks, optionally pin tasks to specific cores. +3. Call `vTaskStartScheduler()` which invokes `xPortStartScheduler()`. +4. `xPortStartScheduler()` configures the primary core tick timer and signals secondary cores that shared init is complete using the `ucPrimaryCoreInitDoneFlag` variable. +5. Wait until all secondary cores report as brought up. +6. Once all cores are up, call `vPortRestoreContext()` to schedule the first task on the primary core. + +Secondary core flow (to be done in each core’s reset handler): + +1. Perform core-specific initialization (e.g., set EL1 stack pointer). +2. Wait for the primary core's signal that shared initialization is complete (i.e., `ucPrimaryCoreInitDoneFlag` set to 1). +3. Update `VBAR_EL1` from the boot vector table to the FreeRTOS vector table. +4. Initialize the GIC redistributor and enable SGIs so interrupts from the primary core are receivable; signal the primary that this secondary is online and ready by setting the its flag in the `ucSecondaryCoresReadyFlags` array. +5. Issue an SVC with immediate value `106` to enter `FreeRTOS_SWI_Handler`, which will call `vPortRestoreContext()` based on the SVC number to start scheduling on this core. diff --git a/portable/GCC/ARM_CR82/port.c b/portable/GCC/ARM_CR82/port.c new file mode 100644 index 000000000..fa150b375 --- /dev/null +++ b/portable/GCC/ARM_CR82/port.c @@ -0,0 +1,873 @@ +/* + * 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 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS + #error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. Refer to Cortex-A equivalent: /* https://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors */ +#endif + +#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET + #error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. Refer to Cortex-A equivalent: /* https://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors */ +#endif + +#ifndef configUNIQUE_INTERRUPT_PRIORITIES + #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. Refer to Cortex-A equivalent: /* https://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors */ +#endif + +#ifndef configSETUP_TICK_INTERRUPT + #error configSETUP_TICK_INTERRUPT() must be defined. Refer to Cortex-A equivalent: /* https://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors */ +#endif /* configSETUP_TICK_INTERRUPT */ + +#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. Refer to Cortex-A equivalent: /* https://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors */ +#endif + +#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 + #error "configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0" +#endif + +#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES + #error "configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority" +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + /* Check the configuration. */ + #if ( configMAX_PRIORITIES > 32 ) + #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice." + #endif +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/* In case security extensions are implemented. */ +#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) + #error "configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )" +#endif + +#ifndef configCLEAR_TICK_INTERRUPT + #error configCLEAR_TICK_INTERRUPT must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. +#endif + +#if configNUMBER_OF_CORES < 1 + #error configNUMBER_OF_CORES must be set to 1 or greater. If the application is not using multiple cores then set configNUMBER_OF_CORES to 1. +#endif /* configNUMBER_OF_CORES < 1 */ + +/* A critical section is exited when the critical section nesting count reaches + * this value. */ +#define portNO_CRITICAL_NESTING ( ( size_t ) 0 ) + +/* Macro to unmask all interrupt priorities. */ +#define portCLEAR_INTERRUPT_PRIORITIES_MASK() __asm volatile ( "SVC %0" : : "i" ( portSVC_UNMASK_ALL_INTERRUPTS ) : "memory" ) + +/* Tasks are not created with a floating point context, but can be given a + * floating point context after they have been created. A variable is stored as + * part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task + * does not have an FPU context, or any other value if the task does have an FPU + * context. */ +#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) + +/* Constants required to setup the initial task context. */ +#define portSP_ELx ( ( StackType_t ) 0x01 ) +#define portSP_EL0 ( ( StackType_t ) 0x00 ) +#define portEL1 ( ( StackType_t ) 0x04 ) +#define portEL0 ( ( StackType_t ) 0x00 ) + +#define portINITIAL_PSTATE ( portEL0 | portSP_EL0 ) + +/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary + * point is zero. */ +#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) + +/* Masks all bits in the APSR other than the mode bits. */ +#define portAPSR_MODE_BITS_MASK ( 0x0C ) + +/* The I bit in the DAIF bits. */ +#define portDAIF_I ( 0x80 ) + +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portBIT_0_SET ( ( uint8_t ) 0x01 ) + +/* The space on the stack required to hold the FPU registers. + * There are 32 128-bit plus 2 64-bit status registers. */ +#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 2 ) + +/*-----------------------------------------------------------*/ + +/* + * Starts the first task executing. This function is necessarily written in + * assembly code so is implemented in portASM.s. + */ +extern void vPortRestoreTaskContext( void ); + +extern void vGIC_EnableIRQ( uint32_t ulInterruptID ); +extern void vGIC_SetPriority( uint32_t ulInterruptID, uint32_t ulPriority ); +extern void vGIC_PowerUpRedistributor( void ); +extern void vGIC_EnableCPUInterface( void ); + +/*-----------------------------------------------------------*/ + +#if ( configNUMBER_OF_CORES == 1 ) + volatile uint64_t ullCriticalNesting = 0ULL; + +/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero + * then floating point context must be saved and restored for the task. */ + uint64_t ullPortTaskHasFPUContext = pdFALSE; + +/* Set to 1 to pend a context switch from an ISR. */ + uint64_t ullPortYieldRequired = pdFALSE; + +/* Counts the interrupt nesting depth. A context switch is only performed if + * if the nesting depth is 0. */ + uint64_t ullPortInterruptNesting = 0; +#else /* #if ( configNUMBER_OF_CORES == 1 ) */ + volatile uint64_t ullCriticalNestings[ configNUMBER_OF_CORES ] = { 0 }; + + /* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero + * then floating point context must be saved and restored for the task. */ + uint64_t ullPortTaskHasFPUContext[ configNUMBER_OF_CORES ] = { pdFALSE }; + uint64_t ullPortYieldRequired[ configNUMBER_OF_CORES ] = { pdFALSE }; + uint64_t ullPortInterruptNestings[ configNUMBER_OF_CORES ] = { 0 }; + + /* Flags to check if the secondary cores are ready. */ + volatile uint8_t ucSecondaryCoresReadyFlags[ configNUMBER_OF_CORES - 1 ] = { 0 }; + volatile uint8_t ucPrimaryCoreInitDoneFlag = 0; +#endif /* #if ( configNUMBER_OF_CORES == 1 ) */ + +/* Used in the ASM code. */ +__attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters ) +{ + /* Setup the initial stack of the task. The stack is set exactly as + * expected by the portRESTORE_CONTEXT() macro. */ + + /* First all the general purpose registers. */ + pxTopOfStack--; + *pxTopOfStack = 0x0101010101010101ULL; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = 0x0303030303030303ULL; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = 0x0202020202020202ULL; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = 0x0505050505050505ULL; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = 0x0404040404040404ULL; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = 0x0707070707070707ULL; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = 0x0606060606060606ULL; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = 0x0909090909090909ULL; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = 0x0808080808080808ULL; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = 0x1111111111111111ULL; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = 0x1010101010101010ULL; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = 0x1313131313131313ULL; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = 0x1212121212121212ULL; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = 0x1515151515151515ULL; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = 0x1414141414141414ULL; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = 0x1717171717171717ULL; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = 0x1616161616161616ULL; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = 0x1919191919191919ULL; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = 0x1818181818181818ULL; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = 0x2121212121212121ULL; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = 0x2020202020202020ULL; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = 0x2323232323232323ULL; /* R23 */ + pxTopOfStack--; + *pxTopOfStack = 0x2222222222222222ULL; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = 0x2525252525252525ULL; /* R25 */ + pxTopOfStack--; + *pxTopOfStack = 0x2424242424242424ULL; /* R24 */ + pxTopOfStack--; + *pxTopOfStack = 0x2727272727272727ULL; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = 0x2626262626262626ULL; /* R26 */ + pxTopOfStack--; + *pxTopOfStack = 0x2929292929292929ULL; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = 0x2828282828282828ULL; /* R28 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ + + pxTopOfStack--; + *pxTopOfStack = portINITIAL_PSTATE; + + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ + + #if ( configUSE_TASK_FPU_SUPPORT == portTASK_NO_FPU_CONTEXT_BY_DEFAULT ) + { + /* The task will start with a critical nesting count of 0 as interrupts are + * enabled. */ + pxTopOfStack--; + *pxTopOfStack = portNO_CRITICAL_NESTING; + + /* The task will start without a floating point context. A task that + * uses the floating point hardware must call vPortTaskUsesFPU() before + * executing any floating point instructions. */ + pxTopOfStack--; + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + } + #elif ( configUSE_TASK_FPU_SUPPORT == portTASK_HAVE_FPU_CONTEXT_BY_DEFAULT ) + { + /* The task will start with a floating point context. Leave enough + * space for the registers - and ensure they are initialised to 0. */ + pxTopOfStack -= portFPU_REGISTER_WORDS; + memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); + + /* The task will start with a critical nesting count of 0 as interrupts are + * enabled. */ + pxTopOfStack--; + *pxTopOfStack = portNO_CRITICAL_NESTING; + + pxTopOfStack--; + *pxTopOfStack = pdTRUE; + #if ( configNUMBER_OF_CORES == 1 ) + ullPortTaskHasFPUContext = pdTRUE; + #else + ullPortTaskHasFPUContext[ portGET_CORE_ID() ] = pdTRUE; + #endif + } + #else /* if ( configUSE_TASK_FPU_SUPPORT == portTASK_NO_FPU_CONTEXT_BY_DEFAULT ) */ + { + #error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined." + } + #endif /* if ( configUSE_TASK_FPU_SUPPORT == portTASK_NO_FPU_CONTEXT_BY_DEFAULT ) */ + + return pxTopOfStack; + +} + +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) +{ + uint64_t ullAPSR; + + #if ( configASSERT_DEFINED == 1 ) + { + volatile uint8_t ucOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine how many priority bits are implemented in the GIC. + * + * Save the interrupt priority value that is about to be clobbered. */ + ucOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to + * all possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Shift to the least significant bits. */ + while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET ) + { + ucMaxPriorityValue >>= ( uint8_t ) 0x01; + } + + /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read + * value. */ + configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY ); + + + /* Restore the clobbered interrupt priority register to its original + * value. */ + *pucFirstUserPriorityRegister = ucOriginalPriority; + } + #endif /* configASSERT_DEFINED */ + + __asm volatile ( "MRS %0, CurrentEL" : "=r" ( ullAPSR ) ); + ullAPSR &= portAPSR_MODE_BITS_MASK; + + configASSERT( ullAPSR == portEL1 ); + + /* Interrupts are turned off in the CPU itself to ensure a tick does + * not execute while the scheduler is being started. Interrupts are + * automatically turned back on in the CPU when the first task starts + * executing. */ + __asm volatile ( "MSR DAIFSET, #2\n" + "DSB SY\n" + "ISB SY\n" ::: "memory" ); + #if ( configNUMBER_OF_CORES > 1 ) + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + ucPrimaryCoreInitDoneFlag = 1; + __asm volatile ( "SEV \n" + "DSB SY \n" + "ISB SY \n" + ::: "memory" ); + /* Hold the primary core here until all the secondary cores are ready, this would be achieved only when + * all elements of ucSecondaryCoresReadyFlags are set. + */ + while( 1 ) + { + BaseType_t xAllCoresReady = pdTRUE; + for( uint32_t ulCoreID = 0; ulCoreID < ( configNUMBER_OF_CORES - 1 ); ulCoreID++ ) + { + if( ucSecondaryCoresReadyFlags[ ulCoreID ] != pdTRUE ) + { + xAllCoresReady = pdFALSE; + break; + } + } + + if ( xAllCoresReady == pdTRUE ) + { + break; + } + } + #else /* if ( configNUMBER_OF_CORES > 1 ) */ + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ + + /* Start the first task executing. */ + vPortRestoreTaskContext(); + + return 0; +} + +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Stub implementation for ports where there is nothing to return to + * Artificially force an assert. */ + configASSERT( NULL ); +} + +/*-----------------------------------------------------------*/ + +#if ( configNUMBER_OF_CORES == 1 ) + void vPortEnterCritical( void ) + { + /* Mask interrupts up to the max syscall interrupt priority. */ + uxPortSetInterruptMask(); + + /* Now interrupts are disabled ullCriticalNesting can be accessed + * directly. Increment ullCriticalNesting to keep a count of how many times + * portENTER_CRITICAL() has been called. */ + ullCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + * assert() if it is being called from an interrupt context. Only API + * functions that end in "FromISR" can be used in an interrupt. Only assert if + * the critical nesting count is 1 to protect against recursive calls if the + * assert function also uses a critical section. */ + if( ullCriticalNesting == 1ULL ) + { + configASSERT( ullPortInterruptNesting == 0 ); + } + } + +/*-----------------------------------------------------------*/ + + void vPortExitCritical( void ) + { + if( ullCriticalNesting > portNO_CRITICAL_NESTING ) + { + /* Decrement the nesting count as the critical section is being + * exited. */ + ullCriticalNesting--; + + /* If the nesting level has reached zero then all interrupt + * priorities must be re-enabled. */ + if( ullCriticalNesting == portNO_CRITICAL_NESTING ) + { + /* Critical nesting has reached zero so all interrupt priorities + * should be unmasked. */ + portCLEAR_INTERRUPT_PRIORITIES_MASK(); + } + } + } +#endif /* if ( configNUMBER_OF_CORES == 1 ) */ + +/*-----------------------------------------------------------*/ + +void FreeRTOS_Tick_Handler( void ) +{ + /* Must be the lowest possible priority. */ + uint64_t ullRunningInterruptPriority; + __asm volatile ( "MRS %0, ICC_RPR_EL1" : "=r" ( ullRunningInterruptPriority ) ); + + configASSERT( ullRunningInterruptPriority == ( portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); + + /* Interrupts should not be enabled before this point. */ + #if ( configASSERT_DEFINED == 1 ) + { + uint64_t ullMaskBits; + + __asm volatile ( "MRS %0, DAIF" : "=r" ( ullMaskBits )::"memory" ); + configASSERT( ( ullMaskBits & portDAIF_I ) != 0 ); + } + #endif /* configASSERT_DEFINED */ + + /* Set interrupt mask before altering scheduler structures. The tick + * handler runs at the lowest priority, so interrupts cannot already be masked, + * so there is no need to save and restore the current mask value. It is + * necessary to turn off interrupts in the CPU itself while the ICCPMR is being + * updated. */ + __asm volatile ( "MSR ICC_PMR_EL1, %0 \n" + "DSB SY \n" + "ISB SY \n" + ::"r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" ); + + /* Ok to enable interrupts after the interrupt source has been cleared. */ + configCLEAR_TICK_INTERRUPT(); + __asm volatile ( "MSR DAIFCLR, #2\n" + "DSB SY\n" + "ISB SY\n" ::: "memory" ); + + #if ( configNUMBER_OF_CORES > 1 ) + UBaseType_t x = portENTER_CRITICAL_FROM_ISR(); + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ + + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + #if ( configNUMBER_OF_CORES == 1 ) + ullPortYieldRequired = pdTRUE; + #else + ullPortYieldRequired[ portGET_CORE_ID() ] = pdTRUE; + #endif + } + #if ( configNUMBER_OF_CORES > 1 ) + portEXIT_CRITICAL_FROM_ISR(x); + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ + + /* Ensure all interrupt priorities are active again. */ + portCLEAR_INTERRUPT_PRIORITIES_MASK(); +} + +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_FPU_SUPPORT == portTASK_NO_FPU_CONTEXT_BY_DEFAULT ) + + void vPortTaskUsesFPU( void ) + { + /* A task is registering the fact that it needs an FPU context. Set the + * FPU flag (which is saved as part of the task context). */ + #if ( configNUMBER_OF_CORES == 1 ) + ullPortTaskHasFPUContext = pdTRUE; + #else + ullPortTaskHasFPUContext[ portGET_CORE_ID() ] = pdTRUE; + #endif + + /* Consider initialising the FPSR here - but probably not necessary in + * AArch64. */ + } + +#endif /* configUSE_TASK_FPU_SUPPORT */ + +/*-----------------------------------------------------------*/ + +void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) +{ + if( uxNewMaskValue == portUNMASK_VALUE ) + { + /* Unmask all interrupt priorities. */ + portCLEAR_INTERRUPT_PRIORITIES_MASK(); + } + else + { + __asm volatile ( + "SVC %0 \n" + : + : "i" ( portSVC_UNMASK_INTERRUPTS ), "r" ( uxNewMaskValue ) + : "memory" + ); + } +} + +void vPortClearInterruptMaskFromISR( UBaseType_t uxNewMaskValue ) +{ + __asm volatile ( + "MSR DAIFSET, #2 \n" + "DSB SY \n" + "ISB SY \n" + "MSR ICC_PMR_EL1, %0 \n" + "DSB SY \n" + "ISB SY \n" + "MSR DAIFCLR, #2 \n" + "DSB SY \n" + "ISB SY \n" + : + : "r" ( uxNewMaskValue ) + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxPortSetInterruptMask( void ) +{ + UBaseType_t ullPMRValue; + + /* Use SVC so this can be called safely from EL0 tasks. */ + __asm volatile ( + "svc %1 \n" + "mov %0, x0 \n" + : "=r" ( ullPMRValue ) + : "i" ( portSVC_MASK_ALL_INTERRUPTS ) + : "x0", "memory" + ); + + return ullPMRValue; +} + +/* EL1/ISR variant to avoid SVC from interrupt context. */ +UBaseType_t uxPortSetInterruptMaskFromISR( void ) +{ + UBaseType_t ullPMRValue; + + __asm volatile ( "MRS %0, ICC_PMR_EL1" : "=r" ( ullPMRValue ) ); + + if( ullPMRValue != ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) + { + __asm volatile ( "MSR DAIFSET, #2 \n" + "DSB SY \n" + "ISB SY \n" + "MSR ICC_PMR_EL1, %0 \n" + "DSB SY \n" + "ISB SY \n" + "MSR DAIFCLR, #2 \n" + "DSB SY \n" + "ISB SY \n" + ::"r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" ); + } + + return ullPMRValue; +} + +/*-----------------------------------------------------------*/ + +#if ( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + /* The following assertion will fail if a service routine (ISR) for + * an interrupt that has been assigned a priority above + * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + * function. ISR safe FreeRTOS API functions must *only* be called + * from interrupts that have been assigned a priority at or below + * configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * Numerically low interrupt priority numbers represent logically high + * interrupt priorities, therefore the priority of the interrupt must + * be set to a value equal to or numerically *higher* than + * configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * FreeRTOS maintains separate thread and ISR API functions to ensure + * interrupt entry is as fast and simple as possible. */ + uint64_t ullRunningInterruptPriority; + __asm volatile ( "MRS %0, ICC_RPR_EL1" : "=r" ( ullRunningInterruptPriority ) ); + configASSERT( ullRunningInterruptPriority >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); + } + +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * If the application provides an implementation of vApplicationIRQHandler(), + * then it will get called directly without saving the FPU registers on + * interrupt entry, and this weak implementation of + * vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors - + * it should never actually get called so its implementation contains a + * call to configASSERT() that will always fail. + * + * If the application provides its own implementation of + * vApplicationFPUSafeIRQHandler() then the implementation of + * vApplicationIRQHandler() provided in portASM.S will save the FPU registers + * before calling it. + * + * Therefore, if the application writer wants FPU registers to be saved on + * interrupt entry their IRQ handler must be called + * vApplicationFPUSafeIRQHandler(), and if the application writer does not want + * FPU registers to be saved on interrupt entry their IRQ handler must be + * called vApplicationIRQHandler(). + */ + __attribute__( ( weak ) ) void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) +{ + ( void ) ulICCIAR; + configASSERT( ( volatile void * ) NULL ); +} + +/*-----------------------------------------------------------*/ + +#if ( configNUMBER_OF_CORES > 1 ) + + /* Which core owns the lock? */ + volatile uint64_t ucOwnedByCore[ portMAX_CORE_COUNT ]; + /* Lock count a core owns. */ + volatile uint64_t ucRecursionCountByLock[ eLockCount ]; + /* Index 0 is used for ISR lock and Index 1 is used for task lock. */ + uint32_t ulGateWord[ eLockCount ]; + + void vInterruptCore( uint32_t ulInterruptID, uint32_t ulCoreID ) + { + uint64_t ulRegVal = 0; + uint32_t ulCoreMask = ( 1UL << ulCoreID ); + ulRegVal |= ( (ulCoreMask & 0xFFFF) | ( ( ulInterruptID & 0xF ) << 24U ) ); + __asm__ volatile ( "msr ICC_SGI1R_EL1, %0" : : "r" ( ulRegVal ) ); + __asm__ volatile ( "dsb sy"); + __asm__ volatile ( "isb sy"); + } + +/*-----------------------------------------------------------*/ + + static inline void prvSpinUnlock( uint32_t * ulLock ) + { + __asm volatile ( + "dmb sy\n" + "mov w1, #0\n" + "str w1, [%x0]\n" + "sev\n" + "dsb sy\n" + "isb sy\n" + : + : "r" ( ulLock ) + : "memory", "w1" + ); + } + +/*-----------------------------------------------------------*/ + + static inline uint32_t prvSpinTrylock( uint32_t * ulLock ) + { + register uint32_t ulRet; + /* Try to acquire spinlock; caller is responsible for further barriers. */ + __asm volatile ( + "1:\n" + "ldxr w1, [%x1]\n" + "cmp w1, #1\n" + "beq 2f\n" + "mov w2, #1\n" + "stxr w1, w2, [%x1]\n" + "cmp w1, #0\n" + "bne 1b\n" + "2:\n" + "mov %w0, w1\n" + : "=r" ( ulRet ) + : "r" ( ulLock ) + : "memory", "w1", "w2" + ); + + return ulRet; + } + +/*-----------------------------------------------------------*/ + + /* Read 64b value shared between cores. */ + static inline uint64_t prvGet64( volatile uint64_t * x ) + { + __asm( "dsb sy" ); + return *x; + } + +/*-----------------------------------------------------------*/ + + /* Write 64b value shared between cores. */ + static inline void prvSet64( volatile uint64_t * x, + uint64_t value ) + { + *x = value; + __asm( "dsb sy" ); + } + +/*-----------------------------------------------------------*/ + + void vPortRecursiveLock( BaseType_t xCoreID, + ePortRTOSLock eLockNum, + BaseType_t uxAcquire ) + { + /* Validate the core ID and lock number. */ + configASSERT( xCoreID < portMAX_CORE_COUNT ); + configASSERT( eLockNum < eLockCount ); + + uint32_t ulLockBit = 1u << eLockNum; + + /* Lock acquire */ + if( uxAcquire ) + { + /* Check if spinlock is available. */ + /* If spinlock is not available check if the core owns the lock. */ + /* If the core owns the lock wait increment the lock count by the core. */ + /* If core does not own the lock wait for the spinlock. */ + if( prvSpinTrylock( &ulGateWord[ eLockNum ] ) != 0 ) + { + /* Check if the core owns the spinlock. */ + if( prvGet64( &ucOwnedByCore[ xCoreID ] ) & ulLockBit ) + { + configASSERT( prvGet64( &ucRecursionCountByLock[ eLockNum ] ) != 255u ); + prvSet64( &ucRecursionCountByLock[ eLockNum ], ( prvGet64( &ucRecursionCountByLock[ eLockNum ] ) + 1 ) ); + return; + } + + /* Preload the gate word into the cache. */ + uint32_t dummy = ulGateWord[ eLockNum ]; + dummy++; + + while( prvSpinTrylock( &ulGateWord[ eLockNum ] ) != 0 ) + { + /* Follow Arm's recommended way of sleeping + * sevl is used to prime the wait loop, + * the first wfe wakes immediately as sevl has set the flag + * the second wfe sleeps the core. This way the core is ensured + * to sleep. + */ + __asm volatile ( "sevl; wfe; wfe" ); + } + } + + /* Add barrier to ensure lock is taken before we proceed. */ + __asm__ __volatile__ ( "dmb sy" ::: "memory" ); + + /* Assert the lock count is 0 when the spinlock is free and is acquired. */ + configASSERT( prvGet64( &ucRecursionCountByLock[ eLockNum ] ) == 0 ); + + /* Set lock count as 1. */ + prvSet64( &ucRecursionCountByLock[ eLockNum ], 1 ); + /* Set ucOwnedByCore. */ + prvSet64( &ucOwnedByCore[ xCoreID ], ( prvGet64( &ucOwnedByCore[ xCoreID ] ) | ulLockBit ) ); + } + /* Lock release. */ + else + { + /* Assert the lock is not free already. */ + configASSERT( ( prvGet64( &ucOwnedByCore[ xCoreID ] ) & ulLockBit ) != 0 ); + configASSERT( prvGet64( &ucRecursionCountByLock[ eLockNum ] ) != 0 ); + + /* Reduce ucRecursionCountByLock by 1. */ + prvSet64( &ucRecursionCountByLock[ eLockNum ], ( prvGet64( &ucRecursionCountByLock[ eLockNum ] ) - 1 ) ); + + if( !prvGet64( &ucRecursionCountByLock[ eLockNum ] ) ) + { + prvSet64( &ucOwnedByCore[ xCoreID ], ( prvGet64( &ucOwnedByCore[ xCoreID ] ) & ~ulLockBit ) ); + prvSpinUnlock( &ulGateWord[ eLockNum ] ); + /* Add barrier to ensure lock status is reflected before we proceed. */ + __asm__ __volatile__ ( "dmb sy" ::: "memory" ); + } + } + } + +/*-----------------------------------------------------------*/ + + BaseType_t xPortGetCoreID( void ) + { + BaseType_t xCoreID; + __asm volatile ( + "svc %1 \n" + "mov %0, x0 \n" + : "=r" ( xCoreID ) + : "i" ( portSVC_GET_CORE_ID ) + : "x0", "memory" + ); + return xCoreID; + } + +/*-----------------------------------------------------------*/ + + void FreeRTOS_SGI_Handler( void ) + { + /* Must be the lowest possible priority. */ + uint64_t ullRunningInterruptPriority; + __asm volatile ( "MRS %0, ICC_RPR_EL1" : "=r" ( ullRunningInterruptPriority ) ); + + configASSERT( ullRunningInterruptPriority == ( portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); + /* Interrupts should not be enabled before this point. */ + #if ( configASSERT_DEFINED == 1 ) + { + uint64_t ullMaskBits; + + __asm volatile ( "mrs %0, DAIF" : "=r" ( ullMaskBits )::"memory" ); + configASSERT( ( ullMaskBits & portDAIF_I ) != 0 ); + } + #endif /* configASSERT_DEFINED */ + + /* Set interrupt mask before altering scheduler structures. The SGI + * handler runs at the lowest priority, so interrupts cannot already be masked, + * so there is no need to save and restore the current mask value. It is + * necessary to turn off interrupts in the CPU itself while the ICCPMR is being + * updated. */ + __asm volatile ( "MSR ICC_PMR_EL1, %0 \n" + "DSB SY \n" + "ISB SY \n" + ::"r" ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) : "memory" ); + + /* Ok to enable interrupts after the interrupt source has been cleared. */ + __asm volatile ( "MSR DAIFCLR, #2\n" + "DSB SY\n" + "ISB SY\n" ::: "memory" ); + + #if ( configNUMBER_OF_CORES == 1 ) + ullPortYieldRequired = pdTRUE; + #else + ullPortYieldRequired[ portGET_CORE_ID() ] = pdTRUE; + #endif + + /* Ensure all interrupt priorities are active again. */ + portCLEAR_INTERRUPT_PRIORITIES_MASK(); + } + +/*-----------------------------------------------------------*/ + +#endif /* if( configNUMBER_OF_CORES > 1 ) */ diff --git a/portable/GCC/ARM_CR82/portASM.S b/portable/GCC/ARM_CR82/portASM.S new file mode 100644 index 000000000..5032a315d --- /dev/null +++ b/portable/GCC/ARM_CR82/portASM.S @@ -0,0 +1,663 @@ +/* + * 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 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * This file is tailored for ARM Cortex-R82 with SMP enabled. + * It includes macros and functions for saving/restoring task context, + * handling interrupts, and supporting multi-core operations. + */ + +#include "FreeRTOSConfig.h" +#include "portmacro.h" + +.text + +/* Variables and functions. */ + .extern ullMaxAPIPriorityMask +#if ( configNUMBER_OF_CORES == 1 ) + .extern pxCurrentTCB + .extern ullCriticalNesting + .extern ullPortInterruptNesting +#else /* #if ( configNUMBER_OF_CORES == 1 ) */ + .extern pxCurrentTCBs + .extern ullCriticalNestings + .extern ullPortInterruptNestings +#endif + .extern vTaskSwitchContext + .extern vApplicationIRQHandler + .extern ullPortTaskHasFPUContext + .extern ullPortYieldRequired + .extern _freertos_vector_table + + .global FreeRTOS_IRQ_Handler + .global FreeRTOS_SWI_Handler + .global vPortRestoreTaskContext + + + .macro saveallgpregisters +/* Save all general-purpose registers on stack. */ +STP X0, X1, [ SP, # - 0x10 ] ! +STP X2, X3, [ SP, # - 0x10 ] ! +STP X4, X5, [ SP, # - 0x10 ] ! +STP X6, X7, [ SP, # - 0x10 ] ! +STP X8, X9, [ SP, # - 0x10 ] ! +STP X10, X11, [ SP, # - 0x10 ] ! +STP X12, X13, [ SP, # - 0x10 ] ! +STP X14, X15, [ SP, # - 0x10 ] ! +STP X16, X17, [ SP, # - 0x10 ] ! +STP X18, X19, [ SP, # - 0x10 ] ! +STP X20, X21, [ SP, # - 0x10 ] ! +STP X22, X23, [ SP, # - 0x10 ] ! +STP X24, X25, [ SP, # - 0x10 ] ! +STP X26, X27, [ SP, # - 0x10 ] ! +STP X28, X29, [ SP, # - 0x10 ] ! +STR X30, [ SP, # - 0x10 ] ! + .endm + +/*-----------------------------------------------------------*/ + + .macro restoreallgpregisters +/* Restore all general-purpose registers from stack. */ +LDR X30, [ SP ], # 0x10 +LDP X28, X29, [ SP ], # 0x10 +LDP X26, X27, [ SP ], # 0x10 +LDP X24, X25, [ SP ], # 0x10 +LDP X22, X23, [ SP ], # 0x10 +LDP X20, X21, [ SP ], # 0x10 +LDP X18, X19, [ SP ], # 0x10 +LDP X16, X17, [ SP ], # 0x10 +LDP X14, X15, [ SP ], # 0x10 +LDP X12, X13, [ SP ], # 0x10 +LDP X10, X11, [ SP ], # 0x10 +LDP X8, X9, [ SP ], # 0x10 +LDP X6, X7, [ SP ], # 0x10 +LDP X4, X5, [ SP ], # 0x10 +LDP X2, X3, [ SP ], # 0x10 +LDP X0, X1, [ SP ], # 0x10 + .endm + +/*-----------------------------------------------------------*/ + + .macro savefuncontextgpregs +/* Save function context general-purpose registers. */ +STP X0, X1, [ SP, # - 0x10 ] ! +STP X2, X3, [ SP, # - 0x10 ] ! +STP X4, X5, [ SP, # - 0x10 ] ! +STP X6, X7, [ SP, # - 0x10 ] ! +STP X8, X9, [ SP, # - 0x10 ] ! +STP X10, X11, [ SP, # - 0x10 ] ! +STP X12, X13, [ SP, # - 0x10 ] ! +STP X14, X15, [ SP, # - 0x10 ] ! +STP X16, X17, [ SP, # - 0x10 ] ! +STP X18, X29, [ SP, # - 0x10 ] ! +STR X30, [ SP, # - 0x10 ] ! + .endm + +/*-----------------------------------------------------------*/ + + .macro restorefuncontextgpregs +/* Restore function context general-purpose registers. */ +LDR X30, [ SP ], # 0x10 +LDP X18, X29, [ SP ], # 0x10 +LDP X16, X17, [ SP ], # 0x10 +LDP X14, X15, [ SP ], # 0x10 +LDP X12, X13, [ SP ], # 0x10 +LDP X10, X11, [ SP ], # 0x10 +LDP X8, X9, [ SP ], # 0x10 +LDP X6, X7, [ SP ], # 0x10 +LDP X4, X5, [ SP ], # 0x10 +LDP X2, X3, [ SP ], # 0x10 +LDP X0, X1, [ SP ], # 0x10 + .endm + +/*-----------------------------------------------------------*/ + + .macro savefloatregisters +/* Save floating-point registers and configuration/status registers. */ +STP Q0, Q1, [ SP, # - 0x20 ] ! +STP Q2, Q3, [ SP, # - 0x20 ] ! +STP Q4, Q5, [ SP, # - 0x20 ] ! +STP Q6, Q7, [ SP, # - 0x20 ] ! +STP Q8, Q9, [ SP, # - 0x20 ] ! +STP Q10, Q11, [ SP, # - 0x20 ] ! +STP Q12, Q13, [ SP, # - 0x20 ] ! +STP Q14, Q15, [ SP, # - 0x20 ] ! +STP Q16, Q17, [ SP, # - 0x20 ] ! +STP Q18, Q19, [ SP, # - 0x20 ] ! +STP Q20, Q21, [ SP, # - 0x20 ] ! +STP Q22, Q23, [ SP, # - 0x20 ] ! +STP Q24, Q25, [ SP, # - 0x20 ] ! +STP Q26, Q27, [ SP, # - 0x20 ] ! +STP Q28, Q29, [ SP, # - 0x20 ] ! +STP Q30, Q31, [ SP, # - 0x20 ] ! +MRS X9, FPSR +MRS X10, FPCR +STP W9, W10, [ SP, # - 0x10 ] ! + .endm + +/*-----------------------------------------------------------*/ + + .macro restorefloatregisters +/* Restore floating-point registers and configuration/status registers. */ +LDP W9, W10, [ SP ], # 0x10 +MSR FPSR, X9 +MSR FPCR, X10 +LDP Q30, Q31, [ SP ], # 0x20 +LDP Q28, Q29, [ SP ], # 0x20 +LDP Q26, Q27, [ SP ], # 0x20 +LDP Q24, Q25, [ SP ], # 0x20 +LDP Q22, Q23, [ SP ], # 0x20 +LDP Q20, Q21, [ SP ], # 0x20 +LDP Q18, Q19, [ SP ], # 0x20 +LDP Q16, Q17, [ SP ], # 0x20 +LDP Q14, Q15, [ SP ], # 0x20 +LDP Q12, Q13, [ SP ], # 0x20 +LDP Q10, Q11, [ SP ], # 0x20 +LDP Q8, Q9, [ SP ], # 0x20 +LDP Q6, Q7, [ SP ], # 0x20 +LDP Q4, Q5, [ SP ], # 0x20 +LDP Q2, Q3, [ SP ], # 0x20 +LDP Q0, Q1, [ SP ], # 0x20 + .endm + +/*-----------------------------------------------------------*/ + + .macro portSAVE_CONTEXT +/* Switch to use the EL0 stack pointer. */ +MSR SPSEL, # 0 +/* Save the entire context. */ +saveallgpregisters +/* Save the SPSR and ELR values. */ +MRS X3, SPSR_EL1 +MRS X2, ELR_EL1 + +STP X2, X3, [ SP, # - 0x10 ] ! + +/* Save the critical section nesting depth. */ +LDR X0, ullCriticalNestingsConst +#if configNUMBER_OF_CORES > 1 + /* Calculate per-core index using MPIDR_EL1 for SMP support. */ + MRS X1, MPIDR_EL1 /* Read the Multiprocessor Affinity Register. */ + AND X1, X1, # 0xff /* Extract Aff0 (core ID). */ + LSL X1, X1, # 3 /* Multiply core ID by pointer size (8 bytes). */ + ADD X0, X0, X1 /* Add offset to base address. */ +#endif +LDR X3, [ X0 ] + +/* Save the FPU context indicator. */ +LDR X0, ullPortTaskHasFPUContextConst +#if configNUMBER_OF_CORES > 1 + ADD X0, X0, X1 /* Add to the base of the FPU array. */ +#endif +LDR X2, [ X0 ] + +/* Save the FPU context, if any (32 128-bit registers). */ +CMP X2, # 0 +B.EQ 1f /* FPU context not present, skip saving FPU registers. */ +savefloatregisters + +1 : +/* Store the critical nesting count and FPU context indicator. */ +STP X2, X3, [ SP, # - 0x10 ] ! +LDR X0, pxCurrentTCBsConst +#if ( configNUMBER_OF_CORES > 1 ) + MRS X1, MPIDR_EL1 /* Read Multiprocessor Affinity Register .*/ + AND X1, X1, # 0xff /* Extract core ID. */ + LSL X1, X1, # 3 /* Multiply core ID by pointer size. */ + ADD X0, X0, X1 /* Offset for current core's TCB pointer. */ +#endif + +LDR X1, [ X0 ] +MOV X0, SP /* Save current stack pointer. */ +STR X0, [ X1 ] + +/* Switch to use the ELx stack pointer. */ +MSR SPSEL, # 1 + .endm + +/*-----------------------------------------------------------*/ + +.macro portRESTORE_CONTEXT +/* Switch to use the EL0 stack pointer. */ +MSR SPSEL, # 0 + +/* Set the SP to point to the stack of the task being restored. */ +LDR X0, pxCurrentTCBsConst +#if configNUMBER_OF_CORES > 1 + /* Get the core ID to index the TCB correctly. */ + MRS X2, MPIDR_EL1 /* Read the Multiprocessor Affinity Register. */ + AND X2, X2, # 0xff /* Extract Aff0 which contains the core ID. */ + LSL X2, X2, # 3 /* Scale the core ID to the size of a pointer (64-bit system). */ + + ADD X0, X0, X2 /* Add the offset for the current core's TCB pointer. */ +#endif +LDR X1, [ X0 ] +LDR X0, [ X1 ] +MOV SP, X0 +LDP X2, X3, [ SP ], # 0x10 /* Retrieve critical nesting and FPU indicator. */ +LDR X0, ullCriticalNestingsConst +/* Calculate offset for current core's ullCriticalNesting. */ +#if configNUMBER_OF_CORES > 1 +/* Existing code to get core ID and scale to pointer size is reused. */ + MRS X1, MPIDR_EL1 /* Read Multiprocessor Affinity Register. */ + AND X1, X1, # 0xff /* Extract Aff0, which contains the core ID. */ + LSL X1, X1, # 3 /* Scale core ID to the size of a pointer (assuming 64-bit system). */ + ADD X0, X0, X1 /* Add offset for the current core's ullCriticalNesting. */ +#endif +MOV X1, # 255 /* Default mask. */ +CMP X3, # 0 +B.EQ 1f +LDR X6, ullMaxAPIPriorityMaskConst +LDR X1, [ X6 ] /* Use computed mask value. */ +1 : +MSR ICC_PMR_EL1, X1 /* Set interrupt mask. */ +DSB SY +ISB SY +STR X3, [ X0 ] /* Restore critical nesting .*/ +/* Restore the FPU context indicator. */ +LDR X0, ullPortTaskHasFPUContextConst +#if configNUMBER_OF_CORES > 1 +/* Existing code to get core ID and scale to pointer size is reused. */ + MRS X1, MPIDR_EL1 /* Read Multiprocessor Affinity Register. */ + AND X1, X1, # 0xff /* Extract Aff0, which contains the core ID. */ + LSL X1, X1, # 3 /* Scale core ID to the size of a pointer (assuming 64-bit system). */ +/* Restore the FPU context indicator. */ + ADD X0, X0, X1 /* Add to the base of the FPU array. */ +#endif +STR X2, [ X0 ] + +/* Restore the FPU context, if any. */ +CMP X2, # 0 +B.EQ 1f +restorefloatregisters +1 : +LDP X2, X3, [ SP ], # 0x10 /* Restore SPSR and ELR. */ +MSR SPSR_EL1, X3 +MSR ELR_EL1, X2 + +restoreallgpregisters +/* Switch to use the ELx stack pointer. */ +MSR SPSEL, # 1 + +ERET + .endm + +/*-----------------------------------------------------------*/ + +/****************************************************************************** + * FreeRTOS_SWI_Handler handler is used to perform a context switch. + *****************************************************************************/ + .align 8 + .type FreeRTOS_SWI_Handler, % function +FreeRTOS_SWI_Handler: +/* Save X0-X2 temporarily as they are used in the handler. */ +STP X0, X1, [SP, #-0x10]! +STR X2, [SP, #-0x10]! +/* Decide action based on SVC immediate without corrupting any task context. */ +MRS X0, ESR_EL1 + +/* Extract exception class. */ +LSR X1, X0, # 26 +CMP X1, # 0x15 /* 0x15 = SVC instruction. */ +B.NE FreeRTOS_Abort + +/* Extract SVC immediate from ISS[15:0]. */ +AND X2, X0, # 0xFFFF + +/* portSVC_START_FIRST_TASK: start first task on this core without saving any prior context. */ +CMP X2, # portSVC_START_FIRST_TASK +B.NE 1f +/* Discard temp-saved X0-X2 before restoring first task. */ +ADD SP, SP, # 0x20 +B Start_First_Task + +1: +/* portSVC_DISABLE_INTERRUPTS: disable IRQs (DAIF.I) without touching task context. */ +CMP X2, # portSVC_DISABLE_INTERRUPTS +B.NE 2f +MSR DAIFSET, # 2 +LDR X2, [SP], #0x10 +LDP X0, X1, [SP], #0x10 +DSB SY +ISB SY +ERET + +2: +/* portSVC_ENABLE_INTERRUPTS: enable IRQs (DAIF.I clear) without touching task context. */ +CMP X2, # portSVC_ENABLE_INTERRUPTS +B.NE 3f +MSR DAIFCLR, # 2 +LDR X2, [SP], #0x10 +LDP X0, X1, [SP], #0x10 +DSB SY +ISB SY +ERET + +3: +/* portSVC_GET_CORE_ID: return core ID in X0 (Aff0 of MPIDR_EL1). */ +CMP X2, # portSVC_GET_CORE_ID +B.NE 4f +MRS X0, MPIDR_EL1 +AND X0, X0, # 0xff +/* Restore X2, then restore X1 while discarding old X0. */ +LDR X2, [ SP ], # 0x10 +LDP XZR, X1, [ SP ], # 0x10 +ERET + +4: +/* portSVC_MASK_ALL_INTERRUPTS: set ICC_PMR_EL1 to max API mask and return previous-mask-equal flag in X0. */ +CMP X2, # portSVC_MASK_ALL_INTERRUPTS +B.NE 5f +/* Load max API mask from ullMaxAPIPriorityMask. */ +LDR X3, ullMaxAPIPriorityMaskConst +LDR X1, [ X3 ] +/* Read current PMR and compare. */ +MRS X2, ICC_PMR_EL1 +CMP X2, X1 +B.EQ 41f +/* Disable IRQs while updating PMR. */ +MSR DAIFSET, # 2 +DSB SY +ISB SY +/* Write new PMR value. */ +MSR ICC_PMR_EL1, X1 +DSB SY +ISB SY +/* Re-enable IRQs. */ +MSR DAIFCLR, # 2 +DSB SY +ISB SY + +41: +MOV X0, X2 /* return ICC_PMR_EL1 original value */ +/* Restore X2, then restore X1 while discarding old X0. */ +LDR X2, [ SP ], # 0x10 +LDP XZR, X1, [ SP ], # 0x10 +ERET + +5: +/* portSVC_UNMASK_ALL_INTERRUPTS: set ICC_PMR_EL1 to portUNMASK_VALUE to unmask all interrupts. */ +CMP X2, # portSVC_UNMASK_ALL_INTERRUPTS +B.NE 6f +/* Disable IRQs while updating PMR. */ +MSR DAIFSET, # 2 +DSB SY +ISB SY +MOV X0, #portUNMASK_VALUE /* Unmask all interrupts. */ +MSR ICC_PMR_EL1, X0 +DSB SY +ISB SY +/* Re-enable IRQs. */ +MSR DAIFCLR, # 2 +DSB SY +ISB SY +LDR X2, [SP], #0x10 +LDP X0, X1, [SP], #0x10 +ERET + +6: +/* portSVC_UNMASK_INTERRUPTS: set ICC_PMR_EL1 to uxNewMaskValue. */ +CMP X2, # portSVC_UNMASK_INTERRUPTS +B.NE 7f +/* Disable IRQs while updating PMR. */ +MSR DAIFSET, # 2 +DSB SY +ISB SY +MOV X0, X1 /* uxNewMaskValue is in X1. */ +MSR ICC_PMR_EL1, X0 +DSB SY +ISB SY +/* Re-enable IRQs. */ +MSR DAIFCLR, # 2 +DSB SY +ISB SY +LDR X2, [SP], #0x10 +LDP X0, X1, [SP], #0x10 +ERET + +7: +/* Default (portSVC_YIELD): yield from a running task. Save context first. */ +/* Restore X0-X2 to their original values before saving full context. */ +LDR X2, [SP], #0x10 +LDP X0, X1, [SP], #0x10 +portSAVE_CONTEXT +#if configNUMBER_OF_CORES > 1 +MRS x0, mpidr_el1 +AND x0, x0, 255 +#endif +BL vTaskSwitchContext +portRESTORE_CONTEXT + +Start_First_Task: +/* Start-first-task path: pick a task and restore it (no prior save). */ +portRESTORE_CONTEXT + +FreeRTOS_Abort: +/* Full ESR is in X0, exception class code is in X1. */ +B . + +/****************************************************************************** + * vPortRestoreTaskContext is used to start the scheduler. + *****************************************************************************/ + .align 8 + .type vPortRestoreTaskContext, % function +vPortRestoreTaskContext: +.set freertos_vector_base, _freertos_vector_table + +/* Install the FreeRTOS interrupt handlers. */ +LDR X1, = freertos_vector_base + MSR VBAR_EL1, X1 +DSB SY +ISB SY + +/* Start the first task. */ + portRESTORE_CONTEXT + + +/****************************************************************************** + * FreeRTOS_IRQ_Handler handles IRQ entry and exit. + * + * This handler is supposed to be used only for IRQs and never for FIQs. Per ARM + * GIC documentation [1], Group 0 interrupts are always signaled as FIQs. Since + * this handler is only for IRQs, We can safely assume Group 1 while accessing + * Interrupt Acknowledge and End Of Interrupt registers and therefore, use + * ICC_IAR1_EL1 and ICC_EOIR1_EL1. + * + * [1] https://developer.arm.com/documentation/198123/0300/Arm-CoreLink-GIC-fundamentals + *****************************************************************************/ + .align 8 + .type FreeRTOS_IRQ_Handler, % function +FreeRTOS_IRQ_Handler: +/* Save volatile registers. */ +savefuncontextgpregs +savefloatregisters + +/* Save the SPSR and ELR. */ +MRS X3, SPSR_EL1 +MRS X2, ELR_EL1 + +STP X2, X3, [ SP, # - 0x10 ] ! + +/* Increment the interrupt nesting counter. */ +LDR X5, ullPortInterruptNestingsConst /* Load base address of the ullPortYieldRequired array */ +#if configNUMBER_OF_CORES > 1 + /* Existing code to get core ID and scale to pointer size is reused. */ + MRS X2, MPIDR_EL1 /* Read Multiprocessor Affinity Register. */ + AND X2, X2, # 0xff /* Extract Aff0, which contains the core ID. */ + LSL X2, X2, # 3 /* Scale core ID to the size of a pointer (assuming 64-bit system). */ + +/* Calculate offset for the current core's ullPortYieldRequired and load its address. */ + ADD X5, X5, X2 /* Add offset for the current core's ullPortYieldRequired. */ +#endif +LDR X1, [ X5 ] /* Old nesting count in X1. */ +ADD X6, X1, # 1 +STR X6, [ X5 ] /* Address of nesting count variable in X5. */ + +/* Maintain the interrupt nesting information across the function call. */ +STP X1, X5, [ SP, # - 0x10 ] ! + +/* Read interrupt ID from the interrupt acknowledge register and store it + * in X0 for future parameter and interrupt clearing use. */ +MRS X0, ICC_IAR1_EL1 + +/* Maintain the interrupt ID value across the function call. */ +STP X0, X1, [ SP, # - 0x10 ] ! + +/* Call the C handler. */ +BL vApplicationIRQHandler + +/* Disable interrupts. */ +MSR DAIFSET, # 2 +DSB SY +ISB SY + +/* Restore the interrupt ID value. */ +LDP X0, X1, [ SP ], # 0x10 + + +/* End IRQ processing by writing interrupt ID value to the EOI register. */ +MSR ICC_EOIR1_EL1, X0 + +/* Restore the critical nesting count. */ +LDP X1, X5, [ SP ], # 0x10 +STR X1, [ X5 ] + +/* Has interrupt nesting unwound? */ +CMP X1, # 0 +B.NE Exit_IRQ_No_Context_Switch + +/* Is a context switch required? */ +LDR X0, ullPortYieldRequiredConst +#if configNUMBER_OF_CORES > 1 +/* Existing code to get core ID and scale to pointer size is reused. */ + MRS X2, MPIDR_EL1 /* Read Multiprocessor Affinity Register. */ + AND X2, X2, # 0xff /* Extract Aff0, which contains the core ID. */ + LSL X2, X2, # 3 /* Scale core ID to the size of a pointer (assuming 64-bit system). */ + +/* Calculate offset for the current core's ullPortYieldRequired and load its address. */ + ADD X0, X0, X2 /* Add offset for the current core's ullPortYieldRequired. */ +#endif +LDR X1, [ X0 ] +CMP X1, # 0 +B.EQ Exit_IRQ_No_Context_Switch + +/* Reset ullPortYieldRequired to 0. */ +MOV X2, # 0 +STR X2, [ X0 ] + +/* Restore volatile registers. */ +LDP X4, X5, [ SP ], # 0x10 /* SPSR and ELR. */ + +MSR SPSR_EL1, X5 +MSR ELR_EL1, X4 +DSB SY +ISB SY + +restorefloatregisters +restorefuncontextgpregs + +/* Save the context of the current task and select a new task to run. */ +portSAVE_CONTEXT +#if configNUMBER_OF_CORES > 1 + MRS x0, mpidr_el1 + AND x0, x0, 255 +#endif +BL vTaskSwitchContext +portRESTORE_CONTEXT + +Exit_IRQ_No_Context_Switch: +/* Restore volatile registers. */ +LDP X4, X5, [ SP ], # 0x10 /* SPSR and ELR. */ + +MSR SPSR_EL1, X5 +MSR ELR_EL1, X4 +DSB SY +ISB SY + +restorefloatregisters +restorefuncontextgpregs + + ERET + +/****************************************************************************** + * If the application provides an implementation of vApplicationIRQHandler(), + * then it will get called directly without saving the FPU registers on + * interrupt entry, and this weak implementation of + * vApplicationIRQHandler() will not get called. + * + * If the application provides its own implementation of + * vApplicationFPUSafeIRQHandler() then this implementation of + * vApplicationIRQHandler() will be called, save the FPU registers, and then + * call vApplicationFPUSafeIRQHandler(). + * + * Therefore, if the application writer wants FPU registers to be saved on + * interrupt entry their IRQ handler must be called + * vApplicationFPUSafeIRQHandler(), and if the application writer does not want + * FPU registers to be saved on interrupt entry their IRQ handler must be + * called vApplicationIRQHandler(). + *****************************************************************************/ + + .align 8 + .weak vApplicationIRQHandler + .type vApplicationIRQHandler, % function +vApplicationIRQHandler: +/* Save LR and FP on the stack. */ +STP X29, X30, [ SP, # - 0x10 ] ! + +/* Save FPU registers (32 128-bits + 2 64-bits configuration and status registers). */ +savefloatregisters + +/* Call the C handler. */ +BL vApplicationFPUSafeIRQHandler + +/* Restore FPU registers. */ +restorefloatregisters + +/* Restore FP and LR. */ +LDP X29, X30, [ SP ], # 0x10 +RET + + .align 8 +#if ( configNUMBER_OF_CORES == 1 ) +pxCurrentTCBsConst:.dword pxCurrentTCB +ullCriticalNestingsConst:.dword ullCriticalNesting +ullPortInterruptNestingsConst:.dword ullPortInterruptNesting +ullPortYieldRequiredConst:.dword ullPortYieldRequired +ullPortTaskHasFPUContextConst:.dword ullPortTaskHasFPUContext +#else +pxCurrentTCBsConst:.dword pxCurrentTCBs +ullCriticalNestingsConst:.dword ullCriticalNestings +ullPortInterruptNestingsConst:.dword ullPortInterruptNestings +ullPortYieldRequiredConst:.dword ullPortYieldRequired +ullPortTaskHasFPUContextConst:.dword ullPortTaskHasFPUContext +#endif /* if ( configNUMBER_OF_CORES == 1 ) */ +ullMaxAPIPriorityMaskConst:.dword ullMaxAPIPriorityMask +vApplicationIRQHandlerConst:.word vApplicationIRQHandler + .end diff --git a/portable/GCC/ARM_CR82/portmacro.h b/portable/GCC/ARM_CR82/portmacro.h new file mode 100644 index 000000000..1617491ef --- /dev/null +++ b/portable/GCC/ARM_CR82/portmacro.h @@ -0,0 +1,297 @@ +/* + * 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 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE size_t +#define portBASE_TYPE long + +#if !defined(__ASSEMBLER__) + typedef portSTACK_TYPE StackType_t; + typedef portBASE_TYPE BaseType_t; + typedef uint64_t UBaseType_t; + + typedef uint64_t TickType_t; + #define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff ) +#endif /* if !defined(__ASSEMBLER__) */ + +/* 64-bit tick type on a 64-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ +#define portTICK_TYPE_IS_ATOMIC 1 + +/*-----------------------------------------------------------*/ + +/* Hardware specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 16 +#define portPOINTER_SIZE_TYPE uint64_t + +/*-----------------------------------------------------------*/ + +/* Task utilities. */ + +#if !defined(__ASSEMBLER__) + /* Called at the end of an ISR that can cause a context switch. */ + #if ( configNUMBER_OF_CORES == 1 ) + #define portEND_SWITCHING_ISR( xSwitchRequired ) \ + { \ + extern uint64_t ullPortYieldRequired; \ + \ + if( xSwitchRequired != pdFALSE ) \ + { \ + ullPortYieldRequired = pdTRUE; \ + } \ + } + #else + #define portEND_SWITCHING_ISR( xSwitchRequired ) \ + { \ + extern uint64_t ullPortYieldRequired[ configNUMBER_OF_CORES ]; \ + \ + if( xSwitchRequired != pdFALSE ) \ + { \ + ullPortYieldRequired[ portGET_CORE_ID() ] = pdTRUE; \ + } \ + } + #endif /* if ( configNUMBER_OF_CORES == 1 ) */ +#endif /* if !defined(__ASSEMBLER__) */ + +/** + * @brief SVC numbers. + */ +#define portSVC_YIELD 105 +#define portSVC_START_FIRST_TASK 106 +#define portSVC_DISABLE_INTERRUPTS 107 +#define portSVC_ENABLE_INTERRUPTS 108 +#define portSVC_GET_CORE_ID 109 +#define portSVC_MASK_ALL_INTERRUPTS 110 +#define portSVC_UNMASK_ALL_INTERRUPTS 111 +#define portSVC_UNMASK_INTERRUPTS 112 + +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +#define portYIELD() __asm volatile ( "SVC %0" : : "i" ( portSVC_YIELD ) : "memory" ) + +/*----------------------------------------------------------- +* Critical section control +*----------------------------------------------------------*/ + +#if !defined(__ASSEMBLER__) + extern UBaseType_t vTaskEnterCriticalFromISR( void ); + extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ); + extern UBaseType_t uxPortSetInterruptMask( void ); + extern UBaseType_t uxPortSetInterruptMaskFromISR( void ); + extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ); + extern void vPortClearInterruptMaskFromISR( UBaseType_t uxNewMaskValue ); + extern void vInterruptCore( uint32_t ulInterruptID, uint32_t ulCoreID ); +#endif /* if !defined(__ASSEMBLER__) */ + +/* Use SVC so this is safe from EL0. EL1 sites in the port use direct MSR. */\ +#define portDISABLE_INTERRUPTS() __asm volatile ( "SVC %0" : : "i" ( portSVC_DISABLE_INTERRUPTS ) : "memory" ) + +#define portENABLE_INTERRUPTS() __asm volatile ( "SVC %0" : : "i" ( portSVC_ENABLE_INTERRUPTS ) : "memory" ) + + +/* In all GICs 255 can be written to the priority mask register to unmask all + * (but the lowest) interrupt priority. */ +#define portUNMASK_VALUE ( 0xFFUL ) + +#if !defined(__ASSEMBLER__) + /* These macros do not globally disable/enable interrupts. They do mask off + * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ + #if ( configNUMBER_OF_CORES == 1 ) + extern void vPortEnterCritical( void ); + extern void vPortExitCritical( void ); + #define portENTER_CRITICAL() vPortEnterCritical() + #define portEXIT_CRITICAL() vPortExitCritical() + #else + #define portENTER_CRITICAL() vTaskEnterCritical() + #define portEXIT_CRITICAL() vTaskExitCritical() + #endif + #define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMaskFromISR() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMaskFromISR( x ) + #define portENTER_CRITICAL_FROM_ISR() vTaskEnterCriticalFromISR() + #define portEXIT_CRITICAL_FROM_ISR( x ) vTaskExitCriticalFromISR( x ) +#endif /* if !defined(__ASSEMBLER__) */ + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are + * not required for this port but included in case common demo code that uses these + * macros is used. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + +#if !defined(__ASSEMBLER__) + /* Prototype of the FreeRTOS tick handler. This must be installed as the + * handler for whichever peripheral is used to generate the RTOS tick. */ + void FreeRTOS_Tick_Handler( void ); +#endif /* if !defined(__ASSEMBLER__) */ + +#define portTASK_NO_FPU_CONTEXT_BY_DEFAULT ( 1U ) +#define portTASK_HAVE_FPU_CONTEXT_BY_DEFAULT ( 2U ) + +/* If configUSE_TASK_FPU_SUPPORT is set to portTASK_NO_FPU_CONTEXT_BY_DEFAULT (1U) + * (or left undefined) then tasks are created without an FPU context and + * must call vPortTaskUsesFPU() to give themselves an FPU context before + * using any FPU instructions. If configUSE_TASK_FPU_SUPPORT is set to + * portTASK_HAVE_FPU_CONTEXT_BY_DEFAULT (2U) then all tasks will have an FPU context + * by default. */ +#if ( configUSE_TASK_FPU_SUPPORT == portTASK_NO_FPU_CONTEXT_BY_DEFAULT ) + void vPortTaskUsesFPU( void ); +#else +/* Each task has an FPU context already, so define this function away to + * nothing to prevent it from being called accidentally. */ + #define vPortTaskUsesFPU() +#endif +#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() + +#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) +#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + +/* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + +/*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +#if ( configASSERT_DEFINED == 1 ) + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif /* configASSERT */ + +#define portNOP() __asm volatile ( "NOP" ) +#define portINLINE __inline + +/* The number of bits to shift for an interrupt priority is dependent on the + * number of bits implemented by the interrupt controller. */ +#if configUNIQUE_INTERRUPT_PRIORITIES == 16 + #define portPRIORITY_SHIFT 4 + #define portMAX_BINARY_POINT_VALUE 3 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 32 + #define portPRIORITY_SHIFT 3 + #define portMAX_BINARY_POINT_VALUE 2 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 64 + #define portPRIORITY_SHIFT 2 + #define portMAX_BINARY_POINT_VALUE 1 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 128 + #define portPRIORITY_SHIFT 1 + #define portMAX_BINARY_POINT_VALUE 0 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 256 + #define portPRIORITY_SHIFT 0 + #define portMAX_BINARY_POINT_VALUE 0 +#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */ + #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware +#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */ + +#define portINTERRUPT_PRIORITY_REGISTER_OFFSET ( 0x400U ) +#define portYIELD_CORE_INT_ID ( 0x0U ) + +#if ( configNUMBER_OF_CORES > 1 ) + + #if !defined(__ASSEMBLER__) + typedef enum + { + eIsrLock = 0, + eTaskLock, + eLockCount + } ePortRTOSLock; + + extern volatile uint64_t ullCriticalNestings[ configNUMBER_OF_CORES ]; + extern void vPortRecursiveLock( BaseType_t xCoreID, + ePortRTOSLock eLockNum, + BaseType_t uxAcquire ); + extern BaseType_t xPortGetCoreID( void ); + #endif /* if !defined(__ASSEMBLER__) */ + + #define portSET_INTERRUPT_MASK() uxPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK( x ) vPortClearInterruptMask( x ) + + #define portMAX_CORE_COUNT configNUMBER_OF_CORES + #define portGET_CORE_ID() xPortGetCoreID() + +/* Use SGI 0 as the yield core interrupt. */ + #define portYIELD_CORE( xCoreID ) vInterruptCore( portYIELD_CORE_INT_ID, ( uint32_t ) xCoreID ) + + #define portRELEASE_ISR_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), eIsrLock, pdFALSE ) + #define portGET_ISR_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), eIsrLock, pdTRUE ) + + #define portRELEASE_TASK_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), eTaskLock, pdFALSE ) + #define portGET_TASK_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), eTaskLock, pdTRUE ) + + #define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( ullCriticalNestings[ ( xCoreID ) ] ) + #define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( ullCriticalNestings[ ( xCoreID ) ] = ( x ) ) + #define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( ullCriticalNestings[ ( xCoreID ) ]++ ) + #define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( ullCriticalNestings[ ( xCoreID ) ]-- ) + +#endif /* configNUMBER_OF_CORES > 1 */ + +#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* PORTMACRO_H */ diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S new file mode 100644 index 000000000..caf31ff76 --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -0,0 +1,867 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* ----------------------------------------------------------------------------------- */ + + .arm + .syntax unified + .section freertos_system_calls, "ax" + +#define FREERTOS_ASSEMBLY + #include "FreeRTOSConfig.h" + #include "portmacro_asm.h" + #include "mpu_syscall_numbers.h" +#undef FREERTOS_ASSEMBLY + +/* ----------------------- Start of Port Specific System Calls ----------------------- */ + +/* + * void vPortYield( void ); + */ +.align 4 +.global vPortYield +.type vPortYield, %function +vPortYield: + SVC #portSVC_YIELD + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vPortSystemCallExit( void ); + */ +.align 4 +.global vPortSystemCallExit +.type vPortSystemCallExit, %function +vPortSystemCallExit: + SVC #portSVC_SYSTEM_CALL_EXIT + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * BaseType_t xPortIsPrivileged( void ); + * + * According to the Procedure Call Standard for the ARM Architecture (AAPCS): + * - Return value must be in R0. + */ +.align 4 +.global xPortIsPrivileged +.type xPortIsPrivileged, %function +xPortIsPrivileged: + MRS R0, CPSR /* R0 = CPSR. */ + AND R0, R0, #0x1F /* R0 = R0 & 0x1F. Extract mode bits.*/ + CMP R0, #USER_MODE /* If R0 == #USER_MODE. */ + MOVEQ R0, #0x0 /* Then, set R0 to 0 to indicate that the processer is not privileged. */ + MOVNE R0, #0x01 /* Otherwise, set R0 to 1 to indicate that the processer is privileged. */ + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); + * + * According to the Procedure Call Standard for the ARM Architecture (AAPCS): + * - Parameter ulBitmap is passed in R0. + * - Return value must be in R0. + */ +.align 4 +.weak ulPortCountLeadingZeros +.type ulPortCountLeadingZeros, %function +ulPortCountLeadingZeros: + CLZ R0, R0 + BX LR + +/* ------------------- End of Port Specific System Calls ------------------- */ + +.macro INVOKE_SYSTEM_CALL systemCallNumber, systemCallImpl + PUSH {R0} + MRS R0, CPSR + AND R0, R0, #0x1F + CMP R0, #USER_MODE + POP {R0} + SVCEQ \systemCallNumber + B \systemCallImpl +.endm + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_xTaskGetTickCountImpl +.align 4 +.global MPU_xTaskGetTickCount +.type MPU_xTaskGetTickCount, function +MPU_xTaskGetTickCount: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetTickCount, MPU_xTaskGetTickCountImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_uxTaskGetNumberOfTasksImpl +.align 4 +.global MPU_uxTaskGetNumberOfTasks +.type MPU_uxTaskGetNumberOfTasks, function +MPU_uxTaskGetNumberOfTasks: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetNumberOfTasks, MPU_uxTaskGetNumberOfTasksImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_vTaskSetTimeOutStateImpl +.align 4 +.global MPU_vTaskSetTimeOutState +.type MPU_vTaskSetTimeOutState, function +MPU_vTaskSetTimeOutState: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetTimeOutState, MPU_vTaskSetTimeOutStateImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_xTaskCheckForTimeOutImpl +.align 4 +.global MPU_xTaskCheckForTimeOut +.type MPU_xTaskCheckForTimeOut, function +MPU_xTaskCheckForTimeOut: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskCheckForTimeOut, MPU_xTaskCheckForTimeOutImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_xQueueGenericSendImpl +.align 4 +.global MPU_xQueueGenericSend +.type MPU_xQueueGenericSend, function +MPU_xQueueGenericSend: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGenericSend, MPU_xQueueGenericSendImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_uxQueueMessagesWaitingImpl +.align 4 +.global MPU_uxQueueMessagesWaiting +.type MPU_uxQueueMessagesWaiting, function +MPU_uxQueueMessagesWaiting: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueMessagesWaiting, MPU_uxQueueMessagesWaitingImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_uxQueueSpacesAvailableImpl +.align 4 +.global MPU_uxQueueSpacesAvailable +.type MPU_uxQueueSpacesAvailable, function +MPU_uxQueueSpacesAvailable: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueSpacesAvailable, MPU_uxQueueSpacesAvailableImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_xQueueReceiveImpl +.align 4 +.global MPU_xQueueReceive +.type MPU_xQueueReceive, function +MPU_xQueueReceive: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueReceive, MPU_xQueueReceiveImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_xQueuePeekImpl +.align 4 +.global MPU_xQueuePeek +.type MPU_xQueuePeek, function +MPU_xQueuePeek: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueuePeek, MPU_xQueuePeekImpl + +/* ----------------------------------------------------------------------------------- */ + +.extern MPU_xQueueSemaphoreTakeImpl +.align 4 +.global MPU_xQueueSemaphoreTake +.type MPU_xQueueSemaphoreTake, function +MPU_xQueueSemaphoreTake: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSemaphoreTake, MPU_xQueueSemaphoreTakeImpl + +/* ----------------------------------------------------------------------------------- */ + +#if ( configUSE_EVENT_GROUPS == 1 ) + + .extern MPU_xEventGroupWaitBitsImpl + .align 4 + .global MPU_xEventGroupWaitBitsEntry + .type MPU_xEventGroupWaitBitsEntry, function + MPU_xEventGroupWaitBitsEntry: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupWaitBits, MPU_xEventGroupWaitBitsImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xEventGroupClearBitsImpl + .align 4 + .global MPU_xEventGroupClearBits + .type MPU_xEventGroupClearBits, function + MPU_xEventGroupClearBits: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupClearBits, MPU_xEventGroupClearBitsImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xEventGroupSetBitsImpl + .align 4 + .global MPU_xEventGroupSetBits + .type MPU_xEventGroupSetBits, function + MPU_xEventGroupSetBits: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSetBits, MPU_xEventGroupSetBitsImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xEventGroupSyncImpl + .align 4 + .global MPU_xEventGroupSync + .type MPU_xEventGroupSync, function + MPU_xEventGroupSync: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSync, MPU_xEventGroupSyncImpl + +#endif /* if ( configUSE_EVENT_GROUPS == 1 ) */ + +/* ----------------------------------------------------------------------------------- */ + +#if ( configUSE_STREAM_BUFFERS == 1 ) + + .extern MPU_xStreamBufferSendImpl + .align 4 + .global MPU_xStreamBufferSend + .type MPU_xStreamBufferSend, function + MPU_xStreamBufferSend: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSend, MPU_xStreamBufferSendImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xStreamBufferReceiveImpl + .align 4 + .global MPU_xStreamBufferReceive + .type MPU_xStreamBufferReceive, function + MPU_xStreamBufferReceive: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferReceive, MPU_xStreamBufferReceiveImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xStreamBufferIsFullImpl + .align 4 + .global MPU_xStreamBufferIsFull + .type MPU_xStreamBufferIsFull, function + MPU_xStreamBufferIsFull: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsFull, MPU_xStreamBufferIsFullImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xStreamBufferIsEmptyImpl + .align 4 + .global MPU_xStreamBufferIsEmpty + .type MPU_xStreamBufferIsEmpty, function + MPU_xStreamBufferIsEmpty: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsEmpty, MPU_xStreamBufferIsEmptyImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xStreamBufferSpacesAvailableImpl + .align 4 + .global MPU_xStreamBufferSpacesAvailable + .type MPU_xStreamBufferSpacesAvailable, function + MPU_xStreamBufferSpacesAvailable: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSpacesAvailable, MPU_xStreamBufferSpacesAvailableImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xStreamBufferBytesAvailableImpl + .align 4 + .global MPU_xStreamBufferBytesAvailable + .type MPU_xStreamBufferBytesAvailable, function + MPU_xStreamBufferBytesAvailable: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferBytesAvailable, MPU_xStreamBufferBytesAvailableImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xStreamBufferSetTriggerLevelImpl + .align 4 + .global MPU_xStreamBufferSetTriggerLevel + .type MPU_xStreamBufferSetTriggerLevel, function + MPU_xStreamBufferSetTriggerLevel: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSetTriggerLevel, MPU_xStreamBufferSetTriggerLevelImpl + + /* ----------------------------------------------------------------------------------- */ + + .extern MPU_xStreamBufferNextMessageLengthBytesImpl + .align 4 + .global MPU_xStreamBufferNextMessageLengthBytes + .type MPU_xStreamBufferNextMessageLengthBytes, function + MPU_xStreamBufferNextMessageLengthBytes: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes, MPU_xStreamBufferNextMessageLengthBytesImpl + +#endif /* if ( configUSE_STREAM_BUFFERS == 1 ) */ + +/* ----------------------------------------------------------------------------------- */ + +#if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) ) + + .extern MPU_xTaskDelayUntilImpl + .align 4 + .global MPU_xTaskDelayUntil + .type MPU_xTaskDelayUntil, function + MPU_xTaskDelayUntil: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskDelayUntil, MPU_xTaskDelayUntilImpl + +#endif /* if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) ) */ + +/* ----------------------------------------------------------------------------------- */ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + .extern MPU_xTaskAbortDelayImpl + .align 4 + .global MPU_xTaskAbortDelay + .type MPU_xTaskAbortDelay, function + MPU_xTaskAbortDelay: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskAbortDelay, MPU_xTaskAbortDelayImpl + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_vTaskDelay == 1 ) + + .extern MPU_vTaskDelayImpl + .align 4 + .global MPU_vTaskDelay + .type MPU_vTaskDelay, function + MPU_vTaskDelay: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskDelay, MPU_vTaskDelayImpl + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + .extern MPU_uxTaskPriorityGetImpl + .align 4 + .global MPU_uxTaskPriorityGet + .type MPU_uxTaskPriorityGet, function + MPU_uxTaskPriorityGet: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskPriorityGet, MPU_uxTaskPriorityGetImpl + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_eTaskGetState == 1 ) + + .extern MPU_eTaskGetStateImpl + .align 4 + .global MPU_eTaskGetState + .type MPU_eTaskGetState, function + MPU_eTaskGetState: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_eTaskGetState, MPU_eTaskGetStateImpl + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + .extern MPU_vTaskGetInfoImpl + .align 4 + .global MPU_vTaskGetInfo + .type MPU_vTaskGetInfo, function + MPU_vTaskGetInfo: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskGetInfo, MPU_vTaskGetInfoImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_uxTaskGetSystemStateImpl + .align 4 + .global MPU_uxTaskGetSystemState + .type MPU_uxTaskGetSystemState, function + MPU_uxTaskGetSystemState: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetSystemState, MPU_uxTaskGetSystemStateImpl + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) + .extern MPU_uxEventGroupGetNumberImpl + .align 4 + .global MPU_uxEventGroupGetNumber + .type MPU_uxEventGroupGetNumber, function + MPU_uxEventGroupGetNumber: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxEventGroupGetNumber, MPU_uxEventGroupGetNumberImpl + + /* ------------------------------------------------------------------------------- */ + + + + .extern MPU_vEventGroupSetNumberImpl + .align 4 + .global MPU_vEventGroupSetNumber + .type MPU_vEventGroupSetNumber, function + MPU_vEventGroupSetNumber: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vEventGroupSetNumber, MPU_vEventGroupSetNumberImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + .extern MPU_xTaskGetIdleTaskHandleImpl + .align 4 + .global MPU_xTaskGetIdleTaskHandle + .type MPU_xTaskGetIdleTaskHandle, function + MPU_xTaskGetIdleTaskHandle: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetIdleTaskHandle, MPU_xTaskGetIdleTaskHandleImpl + + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + .extern MPU_vTaskSuspendImpl + .align 4 + .global MPU_vTaskSuspend + .type MPU_vTaskSuspend, function + MPU_vTaskSuspend: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSuspend, MPU_vTaskSuspendImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_vTaskResumeImpl + .align 4 + .global MPU_vTaskResume + .type MPU_vTaskResume, function + MPU_vTaskResume: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskResume, MPU_vTaskResumeImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + .extern MPU_ulTaskGetRunTimeCounterImpl + .align 4 + .global MPU_ulTaskGetRunTimeCounter + .type MPU_ulTaskGetRunTimeCounter, function + MPU_ulTaskGetRunTimeCounter: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimeCounter, MPU_ulTaskGetRunTimeCounterImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_ulTaskGetRunTimePercentImpl + .align 4 + .global MPU_ulTaskGetRunTimePercent + .type MPU_ulTaskGetRunTimePercent, function + MPU_ulTaskGetRunTimePercent: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimePercent, MPU_ulTaskGetRunTimePercentImpl + + /* ------------------------------------------------------------------------------- */ + + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + .extern MPU_ulTaskGetIdleRunTimePercentImpl + .align 4 + .global MPU_ulTaskGetIdleRunTimePercent + .type MPU_ulTaskGetIdleRunTimePercent, function + MPU_ulTaskGetIdleRunTimePercent: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimePercent, MPU_ulTaskGetIdleRunTimePercentImpl + + /* --------------------------------------------------------------------------- */ + + .extern MPU_ulTaskGetIdleRunTimeCounterImpl + .align 4 + .global MPU_ulTaskGetIdleRunTimeCounter + .type MPU_ulTaskGetIdleRunTimeCounter, function + MPU_ulTaskGetIdleRunTimeCounter: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter, MPU_ulTaskGetIdleRunTimeCounterImpl + + /* --------------------------------------------------------------------------- */ + + #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ + +#endif /* if ( configGENERATE_RUN_TIME_STATS == 1 )*/ + +/* --------------------------------------------------------------------------- */ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + .extern MPU_vTaskSetApplicationTaskTagImpl + .align 4 + .global MPU_vTaskSetApplicationTaskTag + .type MPU_vTaskSetApplicationTaskTag, function + MPU_vTaskSetApplicationTaskTag: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetApplicationTaskTag, MPU_vTaskSetApplicationTaskTagImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTaskGetApplicationTaskTagImpl + .align 4 + .global MPU_xTaskGetApplicationTaskTag + .type MPU_xTaskGetApplicationTaskTag, function + MPU_xTaskGetApplicationTaskTag: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetApplicationTaskTag, MPU_xTaskGetApplicationTaskTagImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + .extern MPU_vTaskSetThreadLocalStoragePointerImpl + .align 4 + .global MPU_vTaskSetThreadLocalStoragePointer + .type MPU_vTaskSetThreadLocalStoragePointer, function + MPU_vTaskSetThreadLocalStoragePointer: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer, MPU_vTaskSetThreadLocalStoragePointerImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_pvTaskGetThreadLocalStoragePointerImpl + .align 4 + .global MPU_pvTaskGetThreadLocalStoragePointer + .type MPU_pvTaskGetThreadLocalStoragePointer, function + MPU_pvTaskGetThreadLocalStoragePointer: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer, MPU_pvTaskGetThreadLocalStoragePointerImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + .extern MPU_uxTaskGetStackHighWaterMarkImpl + .align 4 + .global MPU_uxTaskGetStackHighWaterMark + .type MPU_uxTaskGetStackHighWaterMark, function + MPU_uxTaskGetStackHighWaterMark: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark, MPU_uxTaskGetStackHighWaterMarkImpl + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + .extern MPU_uxTaskGetStackHighWaterMark2Impl + .align 4 + .global MPU_uxTaskGetStackHighWaterMark2 + .type MPU_uxTaskGetStackHighWaterMark2, function + MPU_uxTaskGetStackHighWaterMark2: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark2, MPU_uxTaskGetStackHighWaterMark2Impl + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + .extern MPU_xTaskGetCurrentTaskHandleImpl + .align 4 + .global MPU_xTaskGetCurrentTaskHandle + .type MPU_xTaskGetCurrentTaskHandle, function + MPU_xTaskGetCurrentTaskHandle: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetCurrentTaskHandle, MPU_xTaskGetCurrentTaskHandleImpl + +#endif /* if( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + + .extern MPU_xTaskGetSchedulerStateImpl + .align 4 + .global MPU_xTaskGetSchedulerState + .type MPU_xTaskGetSchedulerState, function + MPU_xTaskGetSchedulerState: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetSchedulerState, MPU_xTaskGetSchedulerStateImpl + + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + .extern MPU_xQueueGetMutexHolderImpl + .align 4 + .global MPU_xQueueGetMutexHolder + .type MPU_xQueueGetMutexHolder, function + MPU_xQueueGetMutexHolder: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGetMutexHolder, MPU_xQueueGetMutexHolderImpl + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + .extern MPU_xQueueTakeMutexRecursiveImpl + .align 4 + .global MPU_xQueueTakeMutexRecursive + .type MPU_xQueueTakeMutexRecursive, function + MPU_xQueueTakeMutexRecursive: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueTakeMutexRecursive, MPU_xQueueTakeMutexRecursiveImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xQueueGiveMutexRecursiveImpl + .align 4 + .global MPU_xQueueGiveMutexRecursive + .type MPU_xQueueGiveMutexRecursive, function + MPU_xQueueGiveMutexRecursive: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGiveMutexRecursive, MPU_xQueueGiveMutexRecursiveImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configUSE_QUEUE_SETS == 1 ) + + .extern MPU_xQueueSelectFromSetImpl + .align 4 + .global MPU_xQueueSelectFromSet + .type MPU_xQueueSelectFromSet, function + MPU_xQueueSelectFromSet: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSelectFromSet, MPU_xQueueSelectFromSetImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xQueueAddToSetImpl + .align 4 + .global MPU_xQueueAddToSet + .type MPU_xQueueAddToSet, function + MPU_xQueueAddToSet: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueAddToSet, MPU_xQueueAddToSetImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + .extern MPU_vQueueAddToRegistryImpl + .align 4 + .global MPU_vQueueAddToRegistry + .type MPU_vQueueAddToRegistry, function + MPU_vQueueAddToRegistry: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueAddToRegistry, MPU_vQueueAddToRegistryImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_vQueueUnregisterQueueImpl + .align 4 + .global MPU_vQueueUnregisterQueue + .type MPU_vQueueUnregisterQueue, function + MPU_vQueueUnregisterQueue: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueUnregisterQueue, MPU_vQueueUnregisterQueueImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_pcQueueGetNameImpl + .align 4 + .global MPU_pcQueueGetName + .type MPU_pcQueueGetName, function + MPU_pcQueueGetName: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcQueueGetName, MPU_pcQueueGetNameImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configUSE_TIMERS == 1 ) + + .extern MPU_pvTimerGetTimerIDImpl + .align 4 + .global MPU_pvTimerGetTimerID + .type MPU_pvTimerGetTimerID, function + MPU_pvTimerGetTimerID: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTimerGetTimerID, MPU_pvTimerGetTimerIDImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_vTimerSetTimerIDImpl + .align 4 + .global MPU_vTimerSetTimerID + .type MPU_vTimerSetTimerID, function + MPU_vTimerSetTimerID: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetTimerID, MPU_vTimerSetTimerIDImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTimerIsTimerActiveImpl + .align 4 + .global MPU_xTimerIsTimerActive + .type MPU_xTimerIsTimerActive, function + MPU_xTimerIsTimerActive: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerIsTimerActive, MPU_xTimerIsTimerActiveImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTimerGetTimerDaemonTaskHandleImpl + .align 4 + .global MPU_xTimerGetTimerDaemonTaskHandle + .type MPU_xTimerGetTimerDaemonTaskHandle, function + MPU_xTimerGetTimerDaemonTaskHandle: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle, MPU_xTimerGetTimerDaemonTaskHandleImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTimerGenericCommandFromTaskImpl + .align 4 + .global MPU_xTimerGenericCommandFromTaskEntry + .type MPU_xTimerGenericCommandFromTaskEntry, function + MPU_xTimerGenericCommandFromTaskEntry: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGenericCommandFromTask, MPU_xTimerGenericCommandFromTaskImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_pcTimerGetNameImpl + .align 4 + .global MPU_pcTimerGetName + .type MPU_pcTimerGetName, function + MPU_pcTimerGetName: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcTimerGetName, MPU_pcTimerGetNameImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_vTimerSetReloadModeImpl + .align 4 + .global MPU_vTimerSetReloadMode + .type MPU_vTimerSetReloadMode, function + MPU_vTimerSetReloadMode: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetReloadMode, MPU_vTimerSetReloadModeImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTimerGetReloadModeImpl + .align 4 + .global MPU_xTimerGetReloadMode + .type MPU_xTimerGetReloadMode, function + MPU_xTimerGetReloadMode: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetReloadMode, MPU_xTimerGetReloadModeImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_uxTimerGetReloadModeImpl + .align 4 + .global MPU_uxTimerGetReloadMode + .type MPU_uxTimerGetReloadMode, function + MPU_uxTimerGetReloadMode: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTimerGetReloadMode, MPU_uxTimerGetReloadModeImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTimerGetPeriodImpl + .align 4 + .global MPU_xTimerGetPeriod + .type MPU_xTimerGetPeriod, function + MPU_xTimerGetPeriod: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetPeriod, MPU_xTimerGetPeriodImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTimerGetExpiryTimeImpl + .align 4 + .global MPU_xTimerGetExpiryTime + .type MPU_xTimerGetExpiryTime, function + MPU_xTimerGetExpiryTime: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetExpiryTime, MPU_xTimerGetExpiryTimeImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( configUSE_TIMERS == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + .extern MPU_xTaskGenericNotifyImpl + .align 4 + .global MPU_xTaskGenericNotifyEntry + .type MPU_xTaskGenericNotifyEntry, function + MPU_xTaskGenericNotifyEntry: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotify, MPU_xTaskGenericNotifyImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTaskGenericNotifyWaitImpl + .align 4 + .global MPU_xTaskGenericNotifyWaitEntry + .type MPU_xTaskGenericNotifyWaitEntry, function + MPU_xTaskGenericNotifyWaitEntry: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyWait, MPU_xTaskGenericNotifyWaitImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_ulTaskGenericNotifyTakeImpl + .align 4 + .global MPU_ulTaskGenericNotifyTake + .type MPU_ulTaskGenericNotifyTake, function + MPU_ulTaskGenericNotifyTake: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyTake, MPU_ulTaskGenericNotifyTakeImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_xTaskGenericNotifyStateClearImpl + .align 4 + .global MPU_xTaskGenericNotifyStateClear + .type MPU_xTaskGenericNotifyStateClear, function + MPU_xTaskGenericNotifyStateClear: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyStateClear, MPU_xTaskGenericNotifyStateClearImpl + + /* ------------------------------------------------------------------------------- */ + + .extern MPU_ulTaskGenericNotifyValueClearImpl + .align 4 + .global MPU_ulTaskGenericNotifyValueClear + .type MPU_ulTaskGenericNotifyValueClear, function + MPU_ulTaskGenericNotifyValueClear: + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyValueClear, MPU_ulTaskGenericNotifyValueClearImpl + + /* ------------------------------------------------------------------------------- */ + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +.end diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c new file mode 100644 index 000000000..6b8d77cd6 --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -0,0 +1,845 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "portmacro.h" +#include "task.h" +#include "mpu_syscall_numbers.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Max value that fits in a uint32_t type. */ +#define portUINT32_MAX ( ~( ( uint32_t ) 0 ) ) + +/* Check if adding a and b will result in overflow. */ +#define portADD_UINT32_WILL_OVERFLOW( a, b ) ( ( a ) > ( portUINT32_MAX - ( b ) ) ) +/* ----------------------------------------------------------------------------------- */ + +/** + * @brief Variable used to keep track of critical section nesting. + * + * @ingroup Critical Sections + * + * This variable is stored as part of the task context and must be initialised + * to a non zero value to ensure interrupts don't inadvertently become unmasked + * before the scheduler starts. As it is stored as part of the task context, it + * will be set to 0 when the first task is started. + */ +PRIVILEGED_DATA volatile UBaseType_t ulCriticalNesting = 0xFFFF; + +/** + * @brief Set to 1 to pend a context switch from an ISR. + * + * @ingroup Interrupt Management + */ +PRIVILEGED_DATA volatile UBaseType_t ulPortYieldRequired = pdFALSE; + +/** + * @brief Interrupt nesting depth, used to count the number of interrupts to unwind. + * + * @ingroup Interrupt Management + */ +PRIVILEGED_DATA volatile UBaseType_t ulPortInterruptNesting = 0UL; + +/** + * @brief Variable to track whether or not the scheduler has been started. + * + * @ingroup Scheduler + * + * This is the port specific version of the xSchedulerRunning in tasks.c. + */ +PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE; + +/* -------------------------- Private Function Declarations -------------------------- */ + +/** + * @brief Determine if the given MPU region settings authorizes the requested + * access to the given buffer. + * + * @ingroup Task Context + * @ingroup MPU Control + * + * @param xTaskMPURegion MPU region settings. + * @param ulBufferStart Start address of the given buffer. + * @param ulBufferLength Length of the given buffer. + * @param ulAccessRequested Access requested. + * + * @return pdTRUE if MPU region settings authorizes the requested access to the + * given buffer, pdFALSE otherwise. + */ +PRIVILEGED_FUNCTION static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulBufferStart, + const uint32_t ulBufferLength, + const uint32_t ulAccessRequested ); + +/** + * @brief Determine the smallest MPU Region Size Encoding for the given MPU + * region size. + * + * @ingroup MPU Control + * + * @param ulActualMPURegionSize MPU region size in bytes. + * + * @return The smallest MPU Region Size Encoding for the given MPU region size. + */ +PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize ); + +/** + * @brief Set up MPU. + * + * @ingroup MPU Control + */ +PRIVILEGED_FUNCTION static void prvSetupMPU( void ); + +/* -------------------------- Exported Function Declarations -------------------------- */ + +/** + * @brief Enter critical section. + * + * @ingroup Critical Section + */ +PRIVILEGED_FUNCTION void vPortEnterCritical( void ); + +/** + * @brief Exit critical section. + * + * @ingroup Critical Section + */ +PRIVILEGED_FUNCTION void vPortExitCritical( void ); + +/* ----------------------------------------------------------------------------------- */ + +/** + * @brief Setup a FreeRTOS task's initial context. + * + * @ingroup Task Context + * + * @param pxTopOfStack Top of stack. + * @param pxCode The task function. + * @param pvParameters Argument passed to the task function. + * @param xRunPrivileged Marks if the task is privileged. + * @param xMPUSettings MPU settings of the task. + * + * @return Location where to restore the task's context from. + */ +/* PRIVILEGED_FUNCTION */ +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) +{ + /* Setup the initial context of the task. The context is set exactly as + * expected by the portRESTORE_CONTEXT() macro. */ + UBaseType_t ulIndex = CONTEXT_SIZE - 1U; + + xSYSTEM_CALL_STACK_INFO * xSysCallInfo = NULL; + + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + /* Current Program Status Register (CPSR). */ + xMPUSettings->ulContext[ ulIndex ] = SYS_MODE; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + /* Current Program Status Register (CPSR). */ + xMPUSettings->ulContext[ ulIndex ] = USER_MODE; + } + + if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x0UL ) + { + /* The task will cause the processor to start in THUMB state, set the + * Thumb state bit in the CPSR. */ + xMPUSettings->ulContext[ ulIndex ] |= portTHUMB_MODE_BIT; + } + + ulIndex--; + + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxCode; /* PC. */ + ulIndex--; + + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex--; + + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxTopOfStack; /* SP. */ + ulIndex--; + + /* General Purpose Registers. */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pvParameters; /* R0. */ + ulIndex--; + + #if( portENABLE_FPU == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000015; /* S31. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1500000; /* S30. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000014; /* S29. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1400000; /* S28. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000013; /* S27. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1300000; /* S26. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000012; /* S25. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1200000; /* S24. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000011; /* S23. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1100000; /* S22. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000010; /* S21. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S20. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000009; /* S19. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD9000000; /* S18. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000008; /* S17. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD8000000; /* S16. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000007; /* S15. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD7000000; /* S14. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000006; /* S13. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD6000000; /* S12. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000005; /* S11. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD5000000; /* S10. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000004; /* S9. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD4000000; /* S8. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000003; /* S7. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD3000000; /* S6. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000002; /* S5. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD2000000; /* S4. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000001; /* S3. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S2. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S1. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S0. */ + ulIndex--; + + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x00000000; /* FPSR. */ + ulIndex--; + } + #endif /* portENABLE_FPU */ + + /* The task will start with a critical nesting count of 0. */ + xMPUSettings->ulContext[ ulIndex ] = portNO_CRITICAL_NESTING; + + /* Ensure that the system call stack is double word aligned. */ + xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo ); + xSysCallInfo->pulSystemCallStackPointer = &( xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] ); + xSysCallInfo->pulSystemCallStackPointer = ( uint32_t * ) ( ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) ) & + ( ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xSysCallInfo->pulTaskStackPointer = NULL; + + /* Set the System Call to return to vPortSystemCallExit. */ + xSysCallInfo->pulSystemCallExitAddress = ( uint32_t * ) ( &vPortSystemCallExit ); + + /* Return the address where this task's context should be restored from. */ + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +/* ----------------------------------------------------------------------------------- */ + +/** + * @brief Store a FreeRTOS task's MPU settings in its TCB. + * + * @ingroup Task Context + * @ingroup MPU Control + * + * @param xMPUSettings The MPU settings in TCB. + * @param xRegions The updated MPU settings requested by the task. + * @param pxBottomOfStack The base address of the task's Stack. + * @param ulStackDepth The length of the task's stack. + */ +/* PRIVILEGED_FUNCTION */ +void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) +{ + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __SRAM_segment_start__; + extern uint32_t * __SRAM_segment_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __SRAM_segment_start__[]; + extern uint32_t __SRAM_segment_end__[]; + #endif /* if defined( __ARMCC_VERSION ) */ + + uint32_t ulIndex = 0x0; + uint32_t ulRegionLength; + uint32_t ulRegionLengthEncoded; + uint32_t ulRegionLengthDecoded; + + if( xRegions == NULL ) + { + /* No MPU regions are specified so allow access to all of the RAM. */ + ulRegionLength = ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); + ulRegionLength |= portMPU_REGION_ENABLE; + + /* MPU Settings is zero'd out in the TCB before this function is called. + * We, therefore, do not need to explicitly zero out unused MPU regions + * in xMPUSettings. */ + ulIndex = portSTACK_REGION; + + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) __SRAM_segment_start__; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded | + portMPU_REGION_ENABLE ); + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ); + } + else + { + for( ulIndex = 0UL; ulIndex < portNUM_CONFIGURABLE_REGIONS; ulIndex++ ) + { + /* If a length has been provided, the region is in use. */ + if( ( xRegions[ ulIndex ] ).ulLengthInBytes > 0UL ) + { + ulRegionLength = xRegions[ ulIndex ].ulLengthInBytes; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); + + /* MPU region base address must be aligned to the region size + * boundary. */ + ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL ); + configASSERT( ( ( ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress ) % ( ulRegionLengthDecoded ) ) == 0UL ); + + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded | + portMPU_REGION_ENABLE ); + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = xRegions[ ulIndex ].ulParameters; + } + else + { + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = 0x0UL; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = 0x0UL; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = 0x0UL; + } + } + + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that the + * stack region has already been configured. */ + if( ulStackDepth != 0x0UL ) + { + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ); + + /* MPU region base address must be aligned to the region size + * boundary. */ + ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL ); + configASSERT( ( ( uint32_t ) pxBottomOfStack % ( ulRegionLengthDecoded ) ) == 0U ); + + ulIndex = portSTACK_REGION; + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded | + portMPU_REGION_ENABLE );; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ); + } + } +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsTaskPrivileged( void ) +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + + /* Calling task's MPU settings. */ + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortStartScheduler( void ) +{ + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + + /* Configure MPU regions that are common to all tasks. */ + prvSetupMPU(); + + prvPortSchedulerRunning = pdTRUE; + + /* Load the context of the first task. */ + vPortStartFirstTask(); + + /* Will only get here if vTaskStartScheduler() was called with the CPU in + * a non-privileged mode or the binary point register was not set to its lowest + * possible value. prvTaskExitError() is referenced to prevent a compiler + * warning about it being defined but not referenced in the case that the user + * defines their own exit address. */ + ( void ) prvTaskExitError(); + return pdFALSE; +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize ) +{ + uint32_t ulRegionSize, ulReturnValue = 4U; + + /* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs. */ + for( ulRegionSize = 0x20UL; ulReturnValue < 0x1FUL; ( ulRegionSize <<= 1UL ) ) + { + if( ulActualMPURegionSize <= ulRegionSize ) + { + break; + } + else + { + ulReturnValue++; + } + } + + /* Shift the code by one before returning so it can be written directly + * into the the correct bit position of the attribute register. */ + return ulReturnValue << 1UL; +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +static void prvSetupMPU( void ) +{ +#if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code. */ + /* Sections used for FLASH. */ + extern uint32_t * __FLASH_segment_start__; + extern uint32_t * __FLASH_segment_end__; + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + + /* Sections used for RAM. */ + extern uint32_t * __SRAM_segment_start__; + extern uint32_t * __SRAM_segment_end__; + extern uint32_t * __privileged_data_start__; + extern uint32_t * __privileged_data_end__; +#else + /* Declaration when these variable are exported from linker scripts. */ + /* Sections used for FLASH. */ + extern uint32_t __FLASH_segment_start__[]; + extern uint32_t __FLASH_segment_end__[]; + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + + /* Sections used for RAM. */ + extern uint32_t __SRAM_segment_start__[]; + extern uint32_t __SRAM_segment_end__[]; + extern uint32_t __privileged_data_start__[]; + extern uint32_t __privileged_data_end__[]; +#endif /* if defined( __ARMCC_VERSION ) */ + + uint32_t ulRegionLength; + uint32_t ulRegionLengthEncoded; + + /* Disable the MPU before programming it. */ + vMPUDisable(); + + /* Priv: RX, Unpriv: RX for entire Flash. */ + ulRegionLength = ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); + vMPUSetRegion( portUNPRIVILEGED_FLASH_REGION, + ( uint32_t ) __FLASH_segment_start__, + ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ), + ( portMPU_REGION_PRIV_RO_USER_RO_EXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) ); + + /* Priv: RX, Unpriv: No access for privileged functions. */ + ulRegionLength = ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); + vMPUSetRegion( portPRIVILEGED_FLASH_REGION, + ( uint32_t ) __privileged_functions_start__, + ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ), + ( portMPU_REGION_PRIV_RO_USER_NA_EXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) ); + + /* Priv: RW, Unpriv: No Access for privileged data. */ + ulRegionLength = ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); + vMPUSetRegion( portPRIVILEGED_RAM_REGION, + ( uint32_t ) __privileged_data_start__, + ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ), + ( portMPU_REGION_PRIV_RW_USER_NA_NOEXEC | + portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ) ); + + /* Enable the MPU background region - it allows privileged operating modes + * access to unmapped regions of memory without generating a fault. */ + vMPUEnableBackgroundRegion(); + + /* After setting default regions, enable the MPU. */ + vMPUEnable(); +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulBufferStart, + const uint32_t ulBufferLength, + const uint32_t ulAccessRequested ) +{ + BaseType_t xAccessGranted = pdFALSE; + uint32_t ulBufferEnd; + uint32_t ulMPURegionLength; + uint32_t ulMPURegionStart; + uint32_t ulMPURegionEnd; + uint32_t ulMPURegionAccessPermissions; + + if( portADD_UINT32_WILL_OVERFLOW( ulBufferStart, ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferEnd = ulBufferStart + ulBufferLength - 1UL; + ulMPURegionLength = 2UL << ( xTaskMPURegion->ulRegionSize >> 1UL ); + ulMPURegionStart = xTaskMPURegion->ulRegionBaseAddress; + ulMPURegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulMPURegionLength - 1UL; + + if( ( ulBufferStart >= ulMPURegionStart ) && + ( ulBufferEnd <= ulMPURegionEnd ) && + ( ulBufferStart <= ulBufferEnd ) ) + { + ulMPURegionAccessPermissions = xTaskMPURegion->ulRegionAttribute & portMPU_REGION_AP_BITMASK; + + if( ulAccessRequested == tskMPU_READ_PERMISSION ) /* RO. */ + { + if( ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RO ) || + ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RO_USER_RO ) || + ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RW ) ) + + { + xAccessGranted = pdTRUE; + } + } + else if( ( ulAccessRequested & tskMPU_WRITE_PERMISSION ) != 0UL ) /* W or RW. */ + { + if( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RW ) + { + xAccessGranted = pdTRUE; + } + } + } + } + + return xAccessGranted; +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) +{ + BaseType_t xAccessGranted = pdFALSE; + uint32_t ulRegionIndex; + xMPU_SETTINGS * xTaskMPUSettings = NULL; + + if( prvPortSchedulerRunning == pdFALSE ) + { + /* Grant access to all the memory before the scheduler is started. It is + * necessary because there is no task running yet and therefore, we + * cannot use the permissions of any task. */ + xAccessGranted = pdTRUE; + } + else + { + /* Calling task's MPU settings. */ + xTaskMPUSettings = xTaskGetMPUSettings( NULL ); + + if( ( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + /* Privileged tasks have access to all the memory. */ + xAccessGranted = pdTRUE; + } + else + { + for( ulRegionIndex = 0x0UL; ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB; ulRegionIndex++ ) + { + xAccessGranted = prvMPURegionAuthorizesBuffer( &( xTaskMPUSettings->xRegion[ ulRegionIndex ] ), + ( uint32_t ) pvBuffer, + ulBufferLength, + ulAccessRequested ); + + if( xAccessGranted == pdTRUE ) + { + break; + } + } + } + } + + return xAccessGranted; +} + +/* ----------------------------------------------------------------------------------- */ + +#if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) +{ + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( prvPortSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + /* Calling task's MPU settings. */ + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject + / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject + % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] ) & + ( 1U << ulAccessControlListEntryBit ) ) != 0UL ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; +} + +#else + +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) +{ + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; +} + +#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +/* ----------------------------------------------------------------------------------- */ + +#if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + +/* PRIVILEGED_FUNCTION */ +void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) +{ + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject + / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject + % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); +} + +#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +/* ----------------------------------------------------------------------------------- */ + +#if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + +/* PRIVILEGED_FUNCTION */ +void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) +{ + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject + / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject + % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); +} + +#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +/* ----------------------------------------------------------------------------------- */ + +void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). + * + * Artificially force an assert() to be triggered if configASSERT() is + * defined, then stop here so application writers can catch the error. */ + configASSERT( ulPortInterruptNesting == ~0UL ); + + for( ;; ) + { + } +} + +/* ----------------------------------------------------------------------------------- */ + +void vPortEndScheduler( void ) +{ + prvPortSchedulerRunning = pdFALSE; + + /* Not implemented in this port. Artificially force an assert. */ + configASSERT( prvPortSchedulerRunning == pdTRUE ); +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + + /* Now that interrupts are disabled, ulCriticalNesting can be accessed + * directly. Increment ulCriticalNesting to keep a count of how many times + * portENTER_CRITICAL() has been called. */ + ulCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + * assert() if it is being called from an interrupt context. Only API + * functions that end in "FromISR" can be used in an interrupt. Only assert + * if the critical nesting count is 1 to protect against recursive calls if + * the assert function also uses a critical section. */ + if( ulCriticalNesting == 1 ) + { + configASSERT( ulPortInterruptNesting == 0 ); + } +} +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +void vPortExitCritical( void ) +{ + if( ulCriticalNesting > portNO_CRITICAL_NESTING ) + { + /* Decrement the nesting count as the critical section is being + * exited. */ + ulCriticalNesting--; + + /* If the nesting level has reached zero then all interrupt + * priorities must be re-enabled. */ + if( ulCriticalNesting == portNO_CRITICAL_NESTING ) + { + /* Critical nesting has reached zero so all interrupt priorities + * should be unmasked. */ + portENABLE_INTERRUPTS(); + } + } +} +/* ----------------------------------------------------------------------------------- */ diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S new file mode 100644 index 000000000..2b6f22ef2 --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -0,0 +1,498 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + .arm + .syntax unified + .section privileged_functions, "ax" + +#define FREERTOS_ASSEMBLY + #include "portmacro_asm.h" + #include "mpu_syscall_numbers.h" +#undef FREERTOS_ASSEMBLY + + /* External FreeRTOS-Kernel variables. */ + .extern pxCurrentTCB + .extern uxSystemCallImplementations + .extern ulPortInterruptNesting + .extern ulPortYieldRequired + + /* External Llnker script variables. */ + .extern __syscalls_flash_start__ + .extern __syscalls_flash_end__ + + /* External FreeRTOS-Kernel functions. */ + .extern vTaskSwitchContext + .extern vApplicationIRQHandler + +/* ----------------------------------------------------------------------------------- */ + +/* Save the context of a FreeRTOS Task. */ +.macro portSAVE_CONTEXT + DSB + ISB + /* Push R0 and LR to the stack for current mode. */ + PUSH { R0, LR } + + LDR LR, =pxCurrentTCB /* LR = &( pxCurrentTCB ). */ + LDR LR, [LR] /* LR = pxCurrentTCB. */ + LDR LR, [LR] /* LR = pxTopOfStack i.e. the address where to store the task context. */ + + LDR R0, =ulCriticalNesting /* R0 = &( ulCriticalNesting ). */ + LDR R0, [R0] /* R0 = ulCriticalNesting. */ + STM LR!, { R0 } /* Store ulCriticalNesting. ! increments LR after storing. */ + +#if ( portENABLE_FPU == 1 ) + VMRS R0, FPSCR /* R0 = FPSCR. */ + STM LR!, { R0 } /* Store FPSCR. */ + VSTM LR!, { D0-D15 } /* Store D0-D15. */ +#endif /* ( portENABLE_FPU == 1 ) */ + + POP { R0 } /* Restore R0 to pre-exception value. */ + /* STM (user registers) - In a PL1 mode other than System mode, STM (user + * registers) instruction stores multiple User mode registers to + * consecutive memory locations using an address from a base register. The + * processor reads the base register value normally, using the current mode + * to determine the correct Banked version of the register. This instruction + * cannot writeback to the base register. + * + * The following can be derived from the above description: + * - The macro portSAVE_CONTEXT MUST be called from a PL1 mode other than + * the System mode. + * - Base register LR of the current mode will be used which contains the + * location to store the context. + * - It will store R0-R14 of User mode i.e. pre-exception SP(R13) and LR(R14) + * will be stored. */ + STM LR, { R0-R14 }^ + ADD LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */ + + POP { R0 } /* Pre-exception PC is in R0. */ + MRS R1, SPSR /* R1 = Pre-exception CPSR. */ + STM LR!, { R0-R1 } /* Store pre-exception PC and CPSR. */ + +.endm + +/* ----------------------------------------------------------------------------------- */ + +/* Restore the context of a FreeRTOS Task. */ +.macro portRESTORE_CONTEXT + /* Load the pointer to the current task's Task Control Block (TCB). */ + LDR LR, =pxCurrentTCB /* LR = &( pxCurrentTCB ). */ + LDR LR, [LR] /* LR = pxCurrentTCB. */ + ADD R1, LR, #0x4 /* R1 now points to the xMPUSettings in TCB. */ + LDR LR, [LR] /* LR = pxTopOfStack i.e. the address where to restore the task context from. */ + + /* When creating a loop label in a macro it has to be a numeric label. + * for( R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portNUM_CONFIGURABLE_REGIONS ; R5++ ) */ + MOV R5, #portFIRST_CONFIGURABLE_REGION + 123: + LDMIA R1!, { R2-R4 } /* R2 = ulRegionSize, R3 = ulRegionAttribute, R4 = ulRegionBaseAddress. */ + + MCR p15, #0, R5, c6, c2, #0 /* MPU Region Number Register. */ + MCR p15, #0, R4, c6, c1, #0 /* MPU Region Base Address Register. */ + MCR p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */ + MCR p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */ + + ADD R5, R5, #1 + CMP R5, #portNUM_CONFIGURABLE_REGIONS + BLE 123b + + LDR R1, =ulCriticalNesting /* R1 = &( ulCriticalNesting ). */ + LDM LR!, { R2 } /* R2 = Stored ulCriticalNesting. */ + STR R2, [R1] /* Restore ulCriticalNesting. */ + +#if ( portENABLE_FPU == 1 ) + LDM LR!, { R1 } /* R1 = Stored FPSCR. */ + VMSR FPSCR, R1 /* Restore FPSCR. */ + VLDM LR!, { D0-D15 } /* Restore D0-D15. */ +#endif /* portENABLE_FPU*/ + + /* LDM (User registers) - In a PL1 mode other than System mode, LDM (User + * registers) loads multiple User mode registers from consecutive memory + * locations using an address from a base register. The registers loaded + * cannot include the PC. The processor reads the base register value + * normally, using the current mode to determine the correct Banked version + * of the register. This instruction cannot writeback to the base register. + * + * The following can be derived from the above description: + * - The macro portRESTORE_CONTEXT MUST be called from a PL1 mode other than + * the System mode. + * - Base register LR of the current mode will be used which contains the + * location to restore the context from. + * - It will restore R0-R14 of User mode i.e. SP(R13) and LR(R14) of User + * mode will be restored. + */ + LDM LR, { R0-R14 }^ + ADD LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */ + + RFE LR /* Restore PC and CPSR from the context. */ + +.endm + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vPortStartFirstTask( void ); + */ +.align 4 +.global vPortStartFirstTask +.type vPortStartFirstTask, %function +vPortStartFirstTask: + /* This function is called from System Mode to start the FreeRTOS-Kernel. + * As described in the portRESTORE_CONTEXT macro, portRESTORE_CONTEXT cannot + * be called from the System mode. We, therefore, switch to the Supervisor + * mode before calling portRESTORE_CONTEXT. */ + CPS #SVC_MODE + portRESTORE_CONTEXT + +/* ----------------------------------------------------------------------------------- */ + +.align 4 +.global FreeRTOS_SVC_Handler +.type FreeRTOS_SVC_Handler, %function +FreeRTOS_SVC_Handler: + PUSH { R11-R12 } + + /* ------------------------- Caller Flash Location Check ------------------------- */ + + LDR R11, =__syscalls_flash_start__ + LDR R12, =__syscalls_flash_end__ + CMP LR, R11 /* If SVC instruction address is less than __syscalls_flash_start__, exit. */ + BLT svcHandlerExit + CMP LR, R12 /* If SVC instruction address is greater than __syscalls_flash_end__, exit. */ + BGT svcHandlerExit + + /* ---------------------------- Get Caller SVC Number ---------------------------- */ + + MRS R11, SPSR /* LR = CPSR at the time of SVC. */ + TST R11, #0x20 /* Check Thumb bit (5) in CPSR. */ + LDRHNE R11, [LR, #-0x2] /* If Thumb, load halfword. */ + BICNE R11, R11, #0xFF00 /* And extract immidiate field (i.e. SVC number). */ + LDREQ R11, [LR, #-0x4] /* If ARM, load word. */ + BICEQ R11, R11, #0xFF000000 /* And extract immidiate field (i.e. SVC number). */ + + /* --------------------------------- SVC Routing --------------------------------- */ + + /* If SVC Number < #NUM_SYSTEM_CALLS, go to svcSystemCallEnter. */ + CMP R11, #NUM_SYSTEM_CALLS + BLT svcSystemCallEnter + + /* If SVC Number == #portSVC_SYSTEM_CALL_EXIT, go to svcSystemCallExit. */ + CMP R11, #portSVC_SYSTEM_CALL_EXIT + BEQ svcSystemCallExit + + /* If SVC Number == #portSVC_YIELD, go to svcPortYield. */ + CMP R11, #portSVC_YIELD + BEQ svcPortYield + +svcHandlerExit: + POP { R11-R12 } + MOVS PC, LR /* Copies the SPSR into the CPSR, performing the mode swap. */ + +svcPortYield: + POP { R11-R12 } + portSAVE_CONTEXT + BL vTaskSwitchContext + portRESTORE_CONTEXT + +svcSystemCallExit: + LDR R11, =pxCurrentTCB /* R11 = &( pxCurrentTCB ). */ + LDR R11, [R11] /* R11 = pxCurrentTCB. */ + ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* R11 now points to xSystemCallStackInfo in TCB. */ + + /* Restore the user mode SP and LR. */ + LDM R11, { R13-R14 }^ + + AND R12, R12, #0x0 /* R12 = 0. */ + STR R12, [R11] /* xSystemCallStackInfo.pulTaskStackPointer = NULL. */ + STR R12, [R11, #0x4] /* xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry = NULL. */ + + LDMDB R11, { R12 } /* R12 = ulTaskFlags. */ + + TST R12, #portTASK_IS_PRIVILEGED_FLAG + /* If the task is privileged, we can exit now. */ + BNE svcHandlerExit + /* Otherwise, we need to switch back to User mode. */ + MRS R12, SPSR + BIC R12, R12, #0x0F + MSR SPSR_cxsf, R12 + + B svcHandlerExit + +svcSystemCallEnter: + LDR R12, =uxSystemCallImplementations /* R12 = uxSystemCallImplementations. */ + /* R12 = uxSystemCallImplementations[ R12 + ( R11 << 2 ) ]. + * R12 now contains the address of the system call impl function. */ + LDR R12, [R12, R11, lsl #2] + + /* If R12 == NULL, exit. */ + CMP R12, #0x0 + BEQ svcHandlerExit + + /* It is okay to clobber LR here because we do not need to return to the + * SVC enter location anymore. LR now contains the address of the system + * call impl function. */ + MOV LR, R12 + + LDR R11, =pxCurrentTCB /* R11 = &( pxCurrentTCB ). */ + LDR R11, [R11] /* R11 = pxCurrentTCB. */ + ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* R11 now points to xSystemCallStackInfo in TCB. */ + + /* Store User mode SP and LR in xSystemCallStackInfo.pulTaskStackPointer and + * xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry. */ + STM R11, { R13-R14 }^ + ADD R11, R11, 0x8 + + /* Load User mode SP an LR with xSystemCallStackInfo.pulSystemCallStackPointer + * and xSystemCallStackInfo.pulSystemCallExitAddress. */ + LDM R11, { R13-R14 }^ + + /* Change to SYS_MODE for the System Call. */ + MRS R12, SPSR + ORR R12, R12, #SYS_MODE + MSR SPSR_cxsf, R12 + + B svcHandlerExit + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vPortDisableInterrupts( void ); + */ +.align 4 +.global vPortDisableInterrupts +.type vPortDisableInterrupts, %function +vPortDisableInterrupts: + CPSID I + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vPortEnableInterrupts( void ); + */ +.align 4 +.global vPortEnableInterrupts +.type vPortEnableInterrupts, %function +vPortEnableInterrupts: + CPSIE I + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vMPUSetRegion( uint32_t ulRegionNumber, + * uint32_t ulBaseAddress, + * uint32_t ulRegionSize, + * uint32_t ulRegionPermissions ); + * + * According to the Procedure Call Standard for the ARM Architecture (AAPCS), + * paramters are passed in the following registers: + * R0 = ulRegionNumber. + * R1 = ulBaseAddress. + * R2 = ulRegionSize. + * R3 = ulRegionPermissions. + */ +.align 4 +.global vMPUSetRegion +.type vMPUSetRegion, %function +vMPUSetRegion: + AND R0, R0, #0x0F /* R0 = R0 & 0x0F. Max possible region number is 15. */ + + MCR p15, #0, R0, c6, c2, #0 /* MPU Region Number Register. */ + MCR p15, #0, R1, c6, c1, #0 /* MPU Region Base Address Register. */ + MCR p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */ + MCR p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */ + + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vMPUEnable( void ); + */ +.align 4 +.global vMPUEnable +.type vMPUEnable, %function +vMPUEnable: + PUSH { R0 } + + MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */ + ORR R0, R0, #0x1 /* R0 = R0 | 0x1. Set the M bit in SCTLR. */ + DSB + MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */ + ISB + + POP { R0 } + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vMPUDisable( void ); + */ +.align 4 +.global vMPUDisable +.type vMPUDisable, %function +vMPUDisable: + PUSH { R0 } + + MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */ + BIC R0, R0, #1 /* R0 = R0 & ~0x1. Clear the M bit in SCTLR. */ + /* Wait for all pending data accesses to complete. */ + DSB + MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */ + /* Flush the pipeline and prefetch buffer(s) in the processor to ensure that + * all following instructions are fetched from cache or memory. */ + ISB + + POP { R0 } + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vMPUEnableBackgroundRegion( void ); + */ +.align 4 +.global vMPUEnableBackgroundRegion +.type vMPUEnableBackgroundRegion, %function +vMPUEnableBackgroundRegion: + PUSH { R0 } + + MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */ + ORR R0, R0, #0x20000 /* R0 = R0 | 0x20000. Set the BR bit in SCTLR. */ + MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */ + + POP { R0 } + BX LR + +/* ----------------------------------------------------------------------------------- */ + +/* + * void vMPUDisableBackgroundRegion( void ); + */ +.align 4 +.global vMPUDisableBackgroundRegion +.type vMPUDisableBackgroundRegion, %function +vMPUDisableBackgroundRegion: + PUSH { R0 } + + MRC p15, 0, R0, c1, c0, 0 /* R0 = System Control Register (SCTLR). */ + BIC R0, R0, #0x20000 /* R0 = R0 & ~0x20000. Clear the BR bit in SCTLR. */ + MCR p15, 0, R0, c1, c0, 0 /* SCTLR = R0. */ + + POP { R0 } + BX LR + +/* ----------------------------------------------------------------------------------- */ + +.align 4 +.global FreeRTOS_IRQ_Handler +.type FreeRTOS_IRQ_Handler, %function +FreeRTOS_IRQ_Handler: + SUB LR, LR, #4 /* Return to the interrupted instruction. */ + SRSDB SP!, #IRQ_MODE /* Save return state (i.e. SPSR_irq and LR_irq) to the IRQ stack. */ + + /* Change to supervisor mode to allow reentry. It is necessary to ensure + * that a BL instruction within the interrupt handler code does not + * overwrite LR_irq. */ + CPS #SVC_MODE + + PUSH { R0-R3, R12 } /* Push AAPCS callee saved registers. */ + + /* Update interrupt nesting count. */ + LDR R0, =ulPortInterruptNesting /* R0 = &( ulPortInterruptNesting ). */ + LDR R1, [R0] /* R1 = ulPortInterruptNesting. */ + ADD R2, R1, #1 /* R2 = R1 + 1. */ + STR R2, [R0] /* Store the updated nesting count. */ + + /* Call the application provided IRQ handler. */ + PUSH { R0-R3, LR } + BL vApplicationIRQHandler + POP { R0-R3, LR } + + /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry. */ + CPSID I + DSB + ISB + + /* Restore the old interrupt nesting count. R0 holds the address of + * ulPortInterruptNesting and R1 holds original value of + * ulPortInterruptNesting. */ + STR R1, [R0] + + /* Context switch is only performed when interrupt nesting count is 0. */ + CMP R1, #0 + BNE exit_without_switch + + /* Check ulPortInterruptNesting to see if the interrupt requested a context + * switch. */ + LDR R1, =ulPortYieldRequired /* R1 = &( ulPortYieldRequired ). */ + LDR R0, [R1] /* R0 = ulPortYieldRequired. */ + /* If ulPortYieldRequired != 0, goto switch_before_exit. */ + CMP R0, #0 + BNE switch_before_exit + +exit_without_switch: + POP { R0-R3, R12 } /* Restore AAPCS callee saved registers. */ + CPS #IRQ_MODE + RFE SP! + +switch_before_exit: + /* A context switch is to be performed. Clear ulPortYieldRequired. R1 holds + * the address of ulPortYieldRequired. */ + MOV R0, #0 + STR R0, [R1] + + /* Restore AAPCS callee saved registers, SPSR_irq and LR_irq before saving + * the task context. */ + POP { R0-R3, R12 } + CPS #IRQ_MODE + /* The contents of the IRQ stack at this point is the following: + * +----------+ + * SP+4 | SPSR_irq | + * +----------+ + * SP | LR_irq | + * +----------+ + */ + LDMIB SP!, { LR } + MSR SPSR_cxsf, LR + LDMDB SP, { LR } + ADD SP, SP, 0x4 + portSAVE_CONTEXT + + /* Call the function that selects the new task to execute. */ + BLX vTaskSwitchContext + + /* Restore the context of, and branch to, the task selected to execute + * next. */ + portRESTORE_CONTEXT + +/* ----------------------------------------------------------------------------------- */ + +.end diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h new file mode 100644 index 000000000..1eb8f0162 --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -0,0 +1,529 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +/** + * @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port + * @file portmacro.h + * @note The settings in this file configure FreeRTOS correctly for the given + * hardware and compiler. These settings should not be altered. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Include stdint for integer types of specific bit widths. */ +#include + +/* ------------------------------ FreeRTOS Config Check ------------------------------ */ + +#ifndef configSYSTEM_CALL_STACK_SIZE + #error "Define configSYSTEM_CALL_STACK_SIZE to a length, in bytes, " \ + "to use when an unprivileged task makes a FreeRTOS Kernel call. " +#endif /* configSYSTEM_CALL_STACK_SIZE */ + +#if( configUSE_MPU_WRAPPERS_V1 == 1 ) + #error This port is usable with MPU wrappers V2 only. +#endif /* configUSE_MPU_WRAPPERS_V1 */ + +#ifndef configSETUP_TICK_INTERRUPT + #error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ + "to call the function that sets up the tick interrupt." +#endif /* configSETUP_TICK_INTERRUPT */ + +/* ----------------------------------------------------------------------------------- */ + +#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when " \ + "configMAX_PRIORITIES is less than or equal to 32. " \ + "It is very rare that a system requires more than 10 to 15 difference " \ + "priorities as tasks that share a priority will time slice." + #endif /* ( configMAX_PRIORITIES > 32 ) */ + + /** + * @brief Mark that a task of the given priority is ready. + * + * @ingroup Scheduler + * + * @param[in] uxPriority Priority of the task that is ready. + * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. + */ + #define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ + ( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) ) + + /** + * @brief Mark that a task of the given priority is no longer ready. + * + * @ingroup Scheduler + * + * @param[in] uxPriority Priority of the task that is no longer ready. + * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. + */ + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ + ( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) ) + + /** + * @brief Determine the highest priority ready task's priority. + * + * @ingroup Scheduler + * + * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. + * @param[in] uxTopPriority The highest priority ready task's priority. + */ + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ) \ + ( uxTopPriority ) = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/* ------------------------------ Port Type Definitions ------------------------------ */ + +#include "portmacro_asm.h" + +/** + * @brief Critical section nesting value. + * + * @ingroup Critical Sections + * + * @note A task exits critical section and enables IRQs when its nesting count + * reaches this value. + */ +#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 ) + +/** + * @brief Bit in Current Program Status Register (CPSR) to indicate that CPU is + * in Thumb State. + * + * @ingroup Task Context + */ +#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) + +/** + * @brief Bitmask to check if an address is of Thumb Code. + * + * @ingroup Task Context + */ +#define portTHUMB_MODE_ADDRESS ( 0x01UL ) + +/** + * @brief Data type used to represent a stack word. + * + * @ingroup Port Interface Specifications + */ +typedef uint32_t StackType_t; + +/** + * @brief Signed data type equal to the data word operating size of the CPU. + * + * @ingroup Port Interface Specifications + */ +typedef int32_t BaseType_t; + +/** + * @brief Unsigned data type equal to the data word operating size of the CPU. + * + * @ingroup Port Interface Specifications + */ +typedef uint32_t UBaseType_t; + +/** + * @brief Data type used for the FreeRTOS Tick Counter. + * + * @note Using 32-bit tick type on a 32-bit architecture ensures that reads of + * the tick count do not need to be guarded with a critical section. + */ +typedef uint32_t TickType_t; + +/** + * @brief Marks the direction the stack grows on the targeted CPU. + * + * @ingroup Port Interface Specifications + */ +#define portSTACK_GROWTH ( -1 ) + +/** + * @brief Specifies stack pointer alignment requirements of the target CPU. + * + * @ingroup Port Interface Specifications + */ +#define portBYTE_ALIGNMENT 8U + +/** + * @brief Task function prototype macro as described on FreeRTOS.org. + * + * @ingroup Port Interface Specifications + * + * @note This is not required for this port but included in case common demo + * code uses it. + */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \ + void vFunction( void * pvParameters ) + +/** + * @brief Task function prototype macro as described on FreeRTOS.org. + * + * @ingroup Port Interface Specifications + * + * @note This is not required for this port but included in case common demo + * code uses it. + */ +#define portTASK_FUNCTION( vFunction, pvParameters ) \ + void vFunction( void * pvParameters ) + +/** + * @brief The no-op ARM assembly instruction. + * + * @ingroup Port Interface Specifications + */ +#define portNOP() __asm volatile( "NOP" ) + +/** + * @brief The inline GCC label. + * + * @ingroup Port Interface Specifications + */ +#define portINLINE __inline + +/** + * @brief The memory access synchronization barrier. + * + * @ingroup Port Interface Specifications + */ +#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) + +/** + * @brief Ensure a symbol isn't removed from the compilation unit. + * + * @ingroup Port Interface Specifications + */ +#define portDONT_DISCARD __attribute__( ( used ) ) + +/** + * @brief Defines if the tick count can be accessed atomically. + * + * @ingroup System Clock + */ +#define portTICK_TYPE_IS_ATOMIC 1 + +/** + * @brief The number of milliseconds between system ticks. + * + * @ingroup System Clock + */ +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ ) + +/** + * @brief The largest possible delay value for any FreeRTOS API. + * + * @ingroup System Clock + */ +#define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFUL + +/* ----------------------------- Port Assembly Functions ----------------------------- */ + +/** + * @brief FreeRTOS Supervisor Call (SVC) Handler. + * + * @ingroup Scheduler + */ +void FreeRTOS_SVC_Handler( void ); + +/** + * @brief FreeRTOS Interrupt Handler. + * + * @ingroup Scheduler + */ +void FreeRTOS_IRQ_Handler( void ); + +/** + * @brief Yield the CPU. + * + * @ingroup Scheduler + */ +void vPortYield( void ); + +#define portYIELD() vPortYield() + +/** + * @brief Enable interrupts. + * + * @ingroup Interrupt Management + */ +void vPortEnableInterrupts( void ); + +#define portENABLE_INTERRUPTS() vPortEnableInterrupts() + +/** + * @brief Disable interrupts. + * + * @ingroup Interrupt Management + */ +void vPortDisableInterrupts( void ); + +#define portDISABLE_INTERRUPTS() vPortDisableInterrupts() + +/** + * @brief Exit from a FreeRTO System Call. + * + * @ingroup Port Privilege + */ +void vPortSystemCallExit( void ); + +/** + * @brief Start executing first task. + * + * @ingroup Scheduler + */ +void vPortStartFirstTask( void ); + +/** + * @brief Enable the onboard MPU. + * + * @ingroup MPU Control + */ +void vMPUEnable( void ); + +/** + * @brief Disable the onboard MPU. + * + * @ingroup MPU Control + */ +void vMPUDisable( void ); + +/** + * @brief Enable the MPU Background Region. + * + * @ingroup MPU Control + */ +void vMPUEnableBackgroundRegion( void ); + +/** + * @brief Disable the MPU Background Region. + * + * @ingroup MPU Control + */ +void vMPUDisableBackgroundRegion( void ); + +/** + * @brief Set permissions for an MPU Region. + * + * @ingroup MPU Control + * + * @param[in] ulRegionNumber The MPU Region Number to set permissions for. + * @param[in] ulBaseAddress The base address of the MPU Region. + * @param[in] ulRegionSize The size of the MPU Region in bytes. + * @param[in] ulRegionPermissions The permissions associated with the MPU Region. + * + * @note This is an internal function and assumes that the inputs to this + * function are checked before calling this function. + */ +void vMPUSetRegion( uint32_t ulRegionNumber, + uint32_t ulBaseAddress, + uint32_t ulRegionSize, + uint32_t ulRegionPermissions ); + +/* ------------------------------- Port.c Declarations ------------------------------- */ + +/** + * @brief Enter critical section. + * + * @ingroup Critical Section + */ +void vPortEnterCritical( void ); + +#define portENTER_CRITICAL() vPortEnterCritical() + +/** + * @brief Exit critical section. + * + * @ingroup Critical Section + */ +void vPortExitCritical( void ); + +#define portEXIT_CRITICAL() vPortExitCritical() + +/** + * @brief Checks whether or not the processor is privileged. + * + * @ingroup Port Privilege + * + * @note The processor privilege level is determined by checking the + * mode bits [4:0] of the Current Program Status Register (CPSR). + * + * @return pdTRUE, if the processor is privileged, pdFALSE otherwise. + */ +BaseType_t xPortIsPrivileged( void ); + +#define portIS_PRIVILEGED() xPortIsPrivileged() + +/** + * @brief Checks whether or not a task is privileged. + * + * @ingroup Port Privilege + * + * @note A task's privilege level is associated with the task and is different from + * the processor's privilege level returned by xPortIsPrivileged. For example, + * the processor is privileged when an unprivileged task executes a system call. + * + * @return pdTRUE if the task is privileged, pdFALSE otherwise. + */ +BaseType_t xPortIsTaskPrivileged( void ); + +#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +/** + * @brief Default return address for tasks. + * + * @ingroup Task Context + * + * @note This function is used as the default return address for tasks if + * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h. + */ +void prvTaskExitError( void ); + +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif /* configTASK_RETURN_ADDRESS */ + +/** + * @brief Returns the number of leading zeros in a 32 bit variable. + * + * @param[in] ulBitmap 32-Bit number to count leading zeros in. + * + * @return The number of leading zeros in ulBitmap. + */ +UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); + +/** + * @brief End the FreeRTOS scheduler. + * + * Not implemented on this port. + * + * @ingroup Scheduler + */ +void vPortEndScheduler( void ); + +/* --------------------------------- MPU Definitions --------------------------------- */ + +/** + * @brief Mark that this port utilizes the onboard ARM MPU. + * + * @ingroup MPU Control + */ +#define portUSING_MPU_WRAPPERS 1 + +/** + * @brief Used to mark if a task should be created as a privileged task. + * + * @ingroup Task Context + * @ingroup MPU Control + * + * @note A privileged task is created by performing a bitwise OR of this value and + * the task priority. For example, to create a privileged task at priority 2, the + * uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ). + */ +#define portPRIVILEGE_BIT ( 0x80000000UL ) + +/** + * @brief Size of an Access Control List (ACL) entry in bits. + */ +#define portACL_ENTRY_SIZE_BITS ( 32UL ) + +/** + * @brief Structure to hold the MPU Register Values. + * + * @struct xMPU_REGION_REGISTERS + * + * @ingroup MPU Control + * + * @note The ordering of this struct MUST be in sync with the ordering in + * portRESTORE_CONTEXT. + */ +typedef struct MPU_REGION_REGISTERS +{ + uint32_t ulRegionSize; /* Information for MPU Region Size and Enable Register. */ + uint32_t ulRegionAttribute; /* Information for MPU Region Access Control Register. */ + uint32_t ulRegionBaseAddress; /* Information for MPU Region Base Address Register. */ +} xMPU_REGION_REGISTERS; + +/** + * @brief Structure to hold per-task System Call Stack information. + * + * @struct xSYSTEM_CALL_STACK_INFO + * + * @ingroup Port Privilege + * + * @note The ordering of this structure MUST be in sync with the assembly code + * of the port. + */ +typedef struct SYSTEM_CALL_STACK_INFO +{ + uint32_t * pulTaskStackPointer; /**< Stack Pointer of the task when it made a FreeRTOS System Call. */ + uint32_t * pulLinkRegisterAtSystemCallEntry; /**< Link Register of the task when it made a FreeRTOS System Call. */ + uint32_t * pulSystemCallStackPointer; /**< Stack Pointer to use for executing a FreeRTOS System Call. */ + uint32_t * pulSystemCallExitAddress; /**< System call exit address. */ + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; /**< Buffer to be used as stack when performing a FreeRTOS System Call. */ +} xSYSTEM_CALL_STACK_INFO; + +/** + * @brief Per-Task MPU settings structure stored in the TCB. + * @struct xMPU_SETTINGS + * + * @ingroup MPU Control + * @ingroup Task Context + * @ingroup Port Privilege + * + * @note The ordering of this structure MUST be in sync with the assembly code + * of the port. + */ +typedef struct MPU_SETTINGS +{ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; + uint32_t ulTaskFlags; + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + uint32_t ulContext[ CONTEXT_SIZE ]; /**< Buffer used to store task context. */ + + #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE + / portACL_ENTRY_SIZE_BITS ) + + 1UL ]; + #endif +} xMPU_SETTINGS; + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h new file mode 100644 index 000000000..c9573e419 --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -0,0 +1,279 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTMACRO_ASM_H +#define PORTMACRO_ASM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FreeRTOSConfig.h" + +#ifndef configTOTAL_MPU_REGIONS + #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" +#elif( configTOTAL_MPU_REGIONS == 12 ) + #define portMPU_TOTAL_REGIONS ( 12UL ) +#elif( configTOTAL_MPU_REGIONS == 16 ) + #define portMPU_TOTAL_REGIONS ( 16UL ) +#else + #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" +#endif /* configTOTAL_MPU_REGIONS */ + +/* + * The application write can disable Floating Point Unit (FPU) support by + * setting configENABLE_FPU to 0. Floating point context stored in TCB + * comprises of 32 floating point registers (D0-D31) and FPSCR register. + * Disabling FPU, therefore, reduces the per-task RAM usage by + * ( 32 + 1 ) * 4 = 132 bytes per task. + * + * BE CAREFUL DISABLING THIS: Certain standard library APIs try to optimize + * themselves by using the floating point registers. If the FPU support is + * disabled, the use of such APIs may result in memory corruption. + */ +#ifndef configENABLE_FPU + #define configENABLE_FPU 1 +#endif /* configENABLE_FPU */ + +#define portENABLE_FPU configENABLE_FPU + +/* On the ArmV7-R Architecture the Operating mode of the Processor is set + * using the Current Program Status Register (CPSR) Mode bits, [4:0]. The only + * unprivileged mode is User Mode. + * + * Additional information about the Processor Modes can be found here: + * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-processor-modes?lang=en + * + */ + +/** + * @brief CPSR bits for various processor modes. + * + * @ingroup Port Privilege + */ +#define USER_MODE 0x10U +#define FIQ_MODE 0x11U +#define IRQ_MODE 0x12U +#define SVC_MODE 0x13U +#define MON_MODE 0x16U +#define ABT_MODE 0x17U +#define HYP_MODE 0x1AU +#define UND_MODE 0x1BU +#define SYS_MODE 0x1FU + +/** + * @brief Flag used to mark that a FreeRTOS Task is privileged. + * + * @ingroup Port Privilege + */ +#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + +/** + * @brief SVC numbers for various scheduler operations. + * + * @ingroup Scheduler + * + * @note These value must not be used in mpu_syscall_numbers.h. + */ +#define portSVC_YIELD 0x0100U +#define portSVC_SYSTEM_CALL_EXIT 0x0104U + +/** + * @brief Macros required to manipulate MPU. + * + * Further information about MPU can be found in Arm's documentation + * https://developer.arm.com/documentation/ddi0363/g/System-Control/Register-descriptions/c6--MPU-memory-region-programming-registers + * + */ + +/* MPU sub-region disable settings. This information is encoded in the MPU + * Region Size and Enable Register. */ +#define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL ) +#define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL ) +#define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL ) +#define portMPU_SUBREGION_3_DISABLE ( 0x1UL << 11UL ) +#define portMPU_SUBREGION_4_DISABLE ( 0x1UL << 12UL ) +#define portMPU_SUBREGION_5_DISABLE ( 0x1UL << 13UL ) +#define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL ) +#define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) + +/* Default MPU regions. */ +#define portFIRST_CONFIGURABLE_REGION ( 0 ) +#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL ) +#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL ) +#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) +#define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) +#define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) +#define portNUM_CONFIGURABLE_REGIONS \ + ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL ) +/* Plus one to make space for the stack region. */ +#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL ) + +/* MPU region sizes. This information is encoded in the MPU Region Size and + * Enable Register. */ +#define portMPU_REGION_SIZE_32B ( 0x04UL << 1UL ) +#define portMPU_REGION_SIZE_64B ( 0x05UL << 1UL ) +#define portMPU_REGION_SIZE_128B ( 0x06UL << 1UL ) +#define portMPU_REGION_SIZE_256B ( 0x07UL << 1UL ) +#define portMPU_REGION_SIZE_512B ( 0x08UL << 1UL ) +#define portMPU_REGION_SIZE_1KB ( 0x09UL << 1UL ) +#define portMPU_REGION_SIZE_2KB ( 0x0AUL << 1UL ) +#define portMPU_REGION_SIZE_4KB ( 0x0BUL << 1UL ) +#define portMPU_REGION_SIZE_8KB ( 0x0CUL << 1UL ) +#define portMPU_REGION_SIZE_16KB ( 0x0DUL << 1UL ) +#define portMPU_REGION_SIZE_32KB ( 0x0EUL << 1UL ) +#define portMPU_REGION_SIZE_64KB ( 0x0FUL << 1UL ) +#define portMPU_REGION_SIZE_128KB ( 0x10UL << 1UL ) +#define portMPU_REGION_SIZE_256KB ( 0x11UL << 1UL ) +#define portMPU_REGION_SIZE_512KB ( 0x12UL << 1UL ) +#define portMPU_REGION_SIZE_1MB ( 0x13UL << 1UL ) +#define portMPU_REGION_SIZE_2MB ( 0x14UL << 1UL ) +#define portMPU_REGION_SIZE_4MB ( 0x15UL << 1UL ) +#define portMPU_REGION_SIZE_8MB ( 0x16UL << 1UL ) +#define portMPU_REGION_SIZE_16MB ( 0x17UL << 1UL ) +#define portMPU_REGION_SIZE_32MB ( 0x18UL << 1UL ) +#define portMPU_REGION_SIZE_64MB ( 0x19UL << 1UL ) +#define portMPU_REGION_SIZE_128MB ( 0x1AUL << 1UL ) +#define portMPU_REGION_SIZE_256MB ( 0x1BUL << 1UL ) +#define portMPU_REGION_SIZE_512MB ( 0x1CUL << 1UL ) +#define portMPU_REGION_SIZE_1GB ( 0x1DUL << 1UL ) +#define portMPU_REGION_SIZE_2GB ( 0x1EUL << 1UL ) +#define portMPU_REGION_SIZE_4GB ( 0x1FUL << 1UL ) + +/* MPU memory types. This information is encoded in the TEX, S, C and B bits + * of the MPU Region Access Control Register. */ +#define portMPU_REGION_STRONGLY_ORDERED_SHAREABLE ( 0x00UL ) /* TEX=000, S=NA, C=0, B=0. */ +#define portMPU_REGION_DEVICE_SHAREABLE ( 0x01UL ) /* TEX=000, S=NA, C=0, B=1. */ +#define portMPU_REGION_NORMAL_OIWTNOWA_NONSHARED ( 0x02UL ) /* TEX=000, S=0, C=1, B=0. */ +#define portMPU_REGION_NORMAL_OIWTNOWA_SHARED ( 0x06UL ) /* TEX=000, S=1, C=1, B=0. */ +#define portMPU_REGION_NORMAL_OIWBNOWA_NONSHARED ( 0x03UL ) /* TEX=000, S=0, C=1, B=1. */ +#define portMPU_REGION_NORMAL_OIWBNOWA_SHARED ( 0x07UL ) /* TEX=000, S=1, C=1, B=1. */ +#define portMPU_REGION_NORMAL_OINC_NONSHARED ( 0x08UL ) /* TEX=001, S=0, C=0, B=0. */ +#define portMPU_REGION_NORMAL_OINC_SHARED ( 0x0CUL ) /* TEX=001, S=1, C=0, B=0. */ +#define portMPU_REGION_NORMAL_OIWBWA_NONSHARED ( 0x0BUL ) /* TEX=001, S=0, C=1, B=1. */ +#define portMPU_REGION_NORMAL_OIWBWA_SHARED ( 0x0FUL ) /* TEX=001, S=1, C=1, B=1. */ +#define portMPU_REGION_DEVICE_NONSHAREABLE ( 0x10UL ) /* TEX=010, S=NA, C=0, B=0. */ + +/* MPU access permissions. This information is encoded in the XN and AP bits of + * the MPU Region Access Control Register. */ +#define portMPU_REGION_AP_BITMASK ( 0x07UL << 8UL ) +#define portMPU_REGION_XN_BITMASK ( 0x01UL << 12UL ) + +#define portMPU_REGION_PRIV_NA_USER_NA ( 0x00UL << 8UL ) +#define portMPU_REGION_PRIV_NA_USER_NA_EXEC ( portMPU_REGION_PRIV_NA_USER_NA ) /* Priv: X, Unpriv: X. */ +#define portMPU_REGION_PRIV_NA_USER_NA_NOEXEC ( portMPU_REGION_PRIV_NA_USER_NA | \ + portMPU_REGION_XN_BITMASK ) /* Priv: No Access, Unpriv: No Access. */ + +#define portMPU_REGION_PRIV_RW_USER_NA ( 0x01UL << 8UL ) +#define portMPU_REGION_PRIV_RW_USER_NA_EXEC ( portMPU_REGION_PRIV_RW_USER_NA ) /* Priv: RWX, Unpriv: X. */ +#define portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RW_USER_NA | \ + portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: No access. */ + +#define portMPU_REGION_PRIV_RW_USER_RO ( 0x02UL << 8UL ) +#define portMPU_REGION_PRIV_RW_USER_RO_EXEC ( portMPU_REGION_PRIV_RW_USER_RO ) /* Priv: RWX, Unpriv: RX. */ +#define portMPU_REGION_PRIV_RW_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RO | \ + portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: R. */ + +#define portMPU_REGION_PRIV_RW_USER_RW ( 0x03UL << 8UL ) +#define portMPU_REGION_PRIV_RW_USER_RW_EXEC ( portMPU_REGION_PRIV_RW_USER_RW ) /* Priv: RWX, Unpriv: RWX. */ +#define portMPU_REGION_PRIV_RW_USER_RW_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RW | \ + portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: RW. */ + +#define portMPU_REGION_PRIV_RO_USER_NA ( 0x05UL << 8UL ) +#define portMPU_REGION_PRIV_RO_USER_NA_EXEC ( portMPU_REGION_PRIV_RO_USER_NA ) /* Priv: RX, Unpriv: X. */ +#define portMPU_REGION_PRIV_RO_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RO_USER_NA | \ + portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: No access. */ + +#define portMPU_REGION_PRIV_RO_USER_RO ( 0x06UL << 8UL ) +#define portMPU_REGION_PRIV_RO_USER_RO_EXEC ( portMPU_REGION_PRIV_RO_USER_RO ) /* Priv: RX, Unpriv: RX. */ +#define portMPU_REGION_PRIV_RO_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RO_USER_RO | \ + portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: R. */ + +/* MPU region management. */ +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) +#define portMPU_REGION_ENABLE ( 0x01UL ) + +/** + * @brief The size (in words) of a task context. + * + * An array of this size is allocated in TCB where a task's context is saved + * when it is switched out. + * + * Information about Floating Point Unit (FPU): + * https://developer.arm.com/documentation/den0042/a/Floating-Point + * + * Additional information related to the Cortex R4-F's FPU Implementation: + * https://developer.arm.com/documentation/ddi0363/e/fpu-programmer-s-model + * + * Additional information related to the Cortex R5-F's FPU Implementation: + * https://developer.arm.com/documentation/ddi0460/d/FPU-Programmers-Model + * + * Additional information related to the ArmV7-R CPSR: + * https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Application-Level-Programmers--Model/The-Application-Program-Status-Register--APSR-?lang=en + * + * Additional information related to the GPRs: + * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-core-registers?lang=en + * + */ + +#if( portENABLE_FPU == 1 ) + /* + * +-------------------+-------+----------+--------+----------+----------+----------+------+ + * | ulCriticalNesting | FPSCR | S0-S31 | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR | + * +-------------------+-------+----------+--------+----------+----------+----------+------+ + * + * <------------------><------><---------><--------><---------><--------><----------><-----> + * 1 1 32 13 1 1 1 1 + */ + #define CONTEXT_SIZE 51U +#else + /* + * +-------------------+--------+----------+----------+----------+------+ + * | ulCriticalNesting | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR | + * +-------------------+--------+----------+----------+----------+------+ + * + * <------------------><--------><---------><--------><----------><-----> + * 1 13 1 1 1 1 + */ + #define CONTEXT_SIZE 18U +#endif /* CONTEXT_SIZE */ + +/** + * @brief Offset of xSystemCallStackInfo from the start of a TCB. + */ +#define portSYSTEM_CALL_INFO_OFFSET \ + ( ( 1U /* pxTopOfStack. */ + \ + ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + \ + 1U /* ulTaskFlags. */ \ + ) * 4U ) + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* PORTMACRO_ASM_H */ diff --git a/portable/GCC/ARM_CRx_No_GIC/port.c b/portable/GCC/ARM_CRx_No_GIC/port.c index ff2abf4ff..bd5a19a49 100644 --- a/portable/GCC/ARM_CRx_No_GIC/port.c +++ b/portable/GCC/ARM_CRx_No_GIC/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -28,6 +28,7 @@ /* Standard includes. */ #include +#include /* Scheduler includes. */ #include "FreeRTOS.h" @@ -80,13 +81,22 @@ #define portTASK_RETURN_ADDRESS prvTaskExitError #endif +/* The space on the stack required to hold the FPU registers. */ +#if ( configFPU_D32 == 1 ) + #define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 ) /* D0-D31 and FPSCR. */ +#else + #define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 ) /* D0-D15 and FPSCR. */ +#endif /* configFPU_D32 */ + /*-----------------------------------------------------------*/ /* - * Starts the first task executing. This function is necessarily written in - * assembly code so is implemented in portASM.s. + * These functions are necessarily written in assembly code, so are implemented + * in portASM.S. */ extern void vPortRestoreTaskContext( void ); +extern void vPortInitialiseFPSCR( void ); +extern uint32_t ulReadAPSR( void ); /* * Used to catch tasks that attempt to return from their implementing function. @@ -184,12 +194,33 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, /* The task will start with a critical nesting count of 0 as interrupts are * enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; - pxTopOfStack--; - /* The task will start without a floating point context. A task that uses - * the floating point hardware must call vPortTaskUsesFPU() before executing - * any floating point instructions. */ - *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + #if ( configUSE_TASK_FPU_SUPPORT == 1 ) + { + /* The task will start without a floating point context. A task that uses + * the floating point hardware must call vPortTaskUsesFPU() before executing + * any floating point instructions. */ + pxTopOfStack--; + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + } + #elif ( configUSE_TASK_FPU_SUPPORT == 2 ) + { + /* The task will start with a floating point context. Leave enough + * space for the registers - and ensure they are initialised to 0. */ + pxTopOfStack -= portFPU_REGISTER_WORDS; + memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); + + /* Initialise the slot containing ulPortTaskHasFPUContext to true as + * the task starts with a floating point context. */ + pxTopOfStack--; + *pxTopOfStack = pdTRUE; + ulPortTaskHasFPUContext = pdTRUE; + } + #else + { + #error "Invalid configUSE_TASK_FPU_SUPPORT value - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined." + } + #endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */ return pxTopOfStack; } @@ -218,7 +249,7 @@ BaseType_t xPortStartScheduler( void ) /* Only continue if the CPU is not in User mode. The CPU must be in a * Privileged mode for the scheduler to start. */ - __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" ); + ulAPSR = ulReadAPSR(); ulAPSR &= portAPSR_MODE_BITS_MASK; configASSERT( ulAPSR != portAPSR_USER_MODE ); @@ -310,15 +341,17 @@ void FreeRTOS_Tick_Handler( void ) } /*-----------------------------------------------------------*/ -void vPortTaskUsesFPU( void ) -{ - uint32_t ulInitialFPSCR = 0; +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) - /* A task is registering the fact that it needs an FPU context. Set the - * FPU flag (which is saved as part of the task context). */ - ulPortTaskHasFPUContext = pdTRUE; + void vPortTaskUsesFPU( void ) + { + /* A task is registering the fact that it needs an FPU context. Set the + * FPU flag (which is saved as part of the task context). */ + ulPortTaskHasFPUContext = pdTRUE; - /* Initialise the floating point status register. */ - __asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" ); -} + /* Initialise the floating point status register. */ + vPortInitialiseFPSCR(); + } + +#endif /* configUSE_TASK_FPU_SUPPORT */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CRx_No_GIC/portASM.S b/portable/GCC/ARM_CRx_No_GIC/portASM.S index bfb15733a..de9845e0f 100644 --- a/portable/GCC/ARM_CRx_No_GIC/portASM.S +++ b/portable/GCC/ARM_CRx_No_GIC/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -28,17 +28,18 @@ .text .arm + .syntax unified - .set SYS_MODE, 0x1f - .set SVC_MODE, 0x13 - .set IRQ_MODE, 0x12 + .set SYS_MODE, 0x1f + .set SVC_MODE, 0x13 + .set IRQ_MODE, 0x12 + .set CPSR_I_BIT, 0x80 /* Variables and functions. */ - .extern ulMaxAPIPriorityMask - .extern _freertos_vector_table .extern pxCurrentTCB .extern vTaskSwitchContext .extern vApplicationIRQHandler + .extern vApplicationFPUSafeIRQHandler .extern ulPortInterruptNesting .extern ulPortTaskHasFPUContext .extern ulICCEOIR @@ -47,29 +48,38 @@ .global FreeRTOS_IRQ_Handler .global FreeRTOS_SVC_Handler .global vPortRestoreTaskContext + .global vPortInitialiseFPSCR + .global ulReadAPSR + .global vPortYield + .global vPortEnableInterrupts + .global vPortDisableInterrupts + .global ulPortSetInterruptMaskFromISR + .global ulPortCountLeadingZeros + .weak vApplicationSVCHandler +/*-----------------------------------------------------------*/ .macro portSAVE_CONTEXT /* Save the LR and SPSR onto the system mode stack before switching to - system mode to save the remaining system mode registers. */ - SRSDB sp!, #SYS_MODE + * system mode to save the remaining system mode registers. */ + SRSDB SP!, #SYS_MODE CPS #SYS_MODE PUSH {R0-R12, R14} /* Push the critical nesting count. */ - LDR R2, ulCriticalNestingConst + LDR R2, =ulCriticalNesting LDR R1, [R2] PUSH {R1} /* Does the task have a floating point context that needs saving? If - ulPortTaskHasFPUContext is 0 then no. */ - LDR R2, ulPortTaskHasFPUContextConst + * ulPortTaskHasFPUContext is 0 then no. */ + LDR R2, =ulPortTaskHasFPUContext LDR R3, [R2] CMP R3, #0 /* Save the floating point context, if any. */ - FMRXNE R1, FPSCR + VMRSNE R1, FPSCR VPUSHNE {D0-D15} #if configFPU_D32 == 1 VPUSHNE {D16-D31} @@ -80,24 +90,24 @@ PUSH {R3} /* Save the stack pointer in the TCB. */ - LDR R0, pxCurrentTCBConst + LDR R0, =pxCurrentTCB LDR R1, [R0] STR SP, [R1] .endm -; /**********************************************************************/ +/*-----------------------------------------------------------*/ .macro portRESTORE_CONTEXT /* Set the SP to point to the stack of the task being restored. */ - LDR R0, pxCurrentTCBConst + LDR R0, =pxCurrentTCB LDR R1, [R0] LDR SP, [R1] /* Is there a floating point context to restore? If the restored - ulPortTaskHasFPUContext is zero then no. */ - LDR R0, ulPortTaskHasFPUContextConst + * ulPortTaskHasFPUContext is zero then no. */ + LDR R0, =ulPortTaskHasFPUContext POP {R1} STR R1, [R0] CMP R1, #0 @@ -111,7 +121,7 @@ VMSRNE FPSCR, R0 /* Restore the critical section nesting depth. */ - LDR R0, ulCriticalNestingConst + LDR R0, =ulCriticalNesting POP {R1} STR R1, [R0] @@ -120,29 +130,17 @@ POP {R0-R12, R14} /* Return to the task code, loading CPSR on the way. */ - RFEIA sp! + RFEIA SP! .endm +/*-----------------------------------------------------------*/ - - -/****************************************************************************** - * SVC handler is used to yield. - *****************************************************************************/ -.align 4 -.type FreeRTOS_SVC_Handler, %function -FreeRTOS_SVC_Handler: - /* Save the context of the current task and select a new task to run. */ - portSAVE_CONTEXT - LDR R0, vTaskSwitchContextConst - BLX R0 - portRESTORE_CONTEXT - - -/****************************************************************************** +/* + * void vPortRestoreTaskContext( void ); + * * vPortRestoreTaskContext is used to start the scheduler. - *****************************************************************************/ + */ .align 4 .type vPortRestoreTaskContext, %function vPortRestoreTaskContext: @@ -150,72 +148,256 @@ vPortRestoreTaskContext: CPS #SYS_MODE portRESTORE_CONTEXT +/*-----------------------------------------------------------*/ + +/* + * void vPortInitialiseFPSCR( void ); + * + * vPortInitialiseFPSCR is used to initialize the FPSCR register. + */ +.align 4 +.type vPortInitialiseFPSCR, %function +vPortInitialiseFPSCR: + MOV R0, #0 + VMSR FPSCR, R0 + BX LR + +/*-----------------------------------------------------------*/ + +/* + * uint32_t ulReadAPSR( void ); + * + * ulReadAPSR is used to read the value of APSR context. + */ +.align 4 +.type ulReadAPSR, %function +ulReadAPSR: + MRS R0, APSR + BX LR + +/*-----------------------------------------------------------*/ + +/* + * void vPortYield( void ); + */ +.align 4 +.type vPortYield, %function +vPortYield: + SVC 0 + ISB + BX LR + +/*-----------------------------------------------------------*/ + +/* + * void vPortEnableInterrupts( void ); + */ +.align 4 +.type vPortEnableInterrupts, %function +vPortEnableInterrupts: + CPSIE I + BX LR + +/*-----------------------------------------------------------*/ + +/* + * void vPortDisableInterrupts( void ); + */ +.align 4 +.type vPortDisableInterrupts, %function +vPortDisableInterrupts: + CPSID I + DSB + ISB + BX LR + +/*-----------------------------------------------------------*/ + +/* + * uint32_t ulPortSetInterruptMaskFromISR( void ); + */ +.align 4 +.type ulPortSetInterruptMaskFromISR, %function +ulPortSetInterruptMaskFromISR: + MRS R0, CPSR + AND R0, R0, #CPSR_I_BIT + CPSID I + DSB + ISB + BX LR + +/*-----------------------------------------------------------*/ + +/* + * void vApplicationSVCHandler( uint32_t ulSvcNumber ); + */ +.align 4 +.type vApplicationSVCHandler, %function +vApplicationSVCHandler: + B vApplicationSVCHandler + +/*-----------------------------------------------------------*/ + +/* If the application provides an implementation of vApplicationIRQHandler(), + * then it will get called directly without saving the FPU registers on + * interrupt entry, and this weak implementation of vApplicationIRQHandler() + * will not get called. + * + * If the application provides its own implementation of + * vApplicationFPUSafeIRQHandler() then this implementation of + * vApplicationIRQHandler() will be called, save the FPU registers, and then + * call vApplicationFPUSafeIRQHandler(). + * + * Therefore, if the application writer wants FPU registers to be saved on + * interrupt entry, their IRQ handler must be called + * vApplicationFPUSafeIRQHandler(), and if the application writer does not want + * FPU registers to be saved on interrupt entry their IRQ handler must be + * called vApplicationIRQHandler(). + */ +.align 4 +.weak vApplicationIRQHandler +.type vApplicationIRQHandler, %function +vApplicationIRQHandler: + PUSH {LR} + + VMRS R1, FPSCR + VPUSH {D0-D7} + PUSH {R1} + + BLX vApplicationFPUSafeIRQHandler + + POP {R0} + VPOP {D0-D7} + VMSR FPSCR, R0 + + POP {PC} + +/*-----------------------------------------------------------*/ + +.align 4 +.weak vApplicationFPUSafeIRQHandler +.type vApplicationFPUSafeIRQHandler, %function +vApplicationFPUSafeIRQHandler: + B vApplicationFPUSafeIRQHandler + +/*-----------------------------------------------------------*/ + +/* + * UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); + * + * According to the Procedure Call Standard for the ARM Architecture (AAPCS): + * - Parameter ulBitmap is passed in R0. + * - Return value must be in R0. + */ +.align 4 +.type ulPortCountLeadingZeros, %function +ulPortCountLeadingZeros: + CLZ R0, R0 + BX LR + +/*-----------------------------------------------------------*/ + +/* + * SVC handler is used to yield. + */ +.align 4 +.type FreeRTOS_SVC_Handler, %function +FreeRTOS_SVC_Handler: + PUSH { R0-R1 } + + /* ---------------------------- Get Caller SVC Number ---------------------------- */ + MRS R0, SPSR /* R0 = CPSR at the time of SVC. */ + TST R0, #0x20 /* Check Thumb bit (5) in CPSR. */ + LDRHNE R0, [LR, #-0x2] /* If Thumb, load halfword. */ + BICNE R0, R0, #0xFF00 /* And extract immidiate field (i.e. SVC number). */ + LDREQ R0, [LR, #-0x4] /* If ARM, load word. */ + BICEQ R0, R0, #0xFF000000 /* And extract immidiate field (i.e. SVC number). */ + + /* --------------------------------- SVC Routing --------------------------------- */ + CMP R0, #0 + BEQ svcPortYield + BNE svcApplicationCall + +svcPortYield: + POP { R0-R1 } + portSAVE_CONTEXT + BLX vTaskSwitchContext + portRESTORE_CONTEXT + +svcApplicationCall: + POP { R0-R1 } + portSAVE_CONTEXT + BLX vApplicationSVCHandler + portRESTORE_CONTEXT + +/*-----------------------------------------------------------*/ + .align 4 .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: /* Return to the interrupted instruction. */ - SUB lr, lr, #4 + SUB LR, LR, #4 /* Push the return address and SPSR. */ - PUSH {lr} - MRS lr, SPSR - PUSH {lr} + PUSH {LR} + MRS LR, SPSR + PUSH {LR} /* Change to supervisor mode to allow reentry. */ - CPS #0x13 + CPS #SVC_MODE /* Push used registers. */ - PUSH {r0-r3, r12} + PUSH {R0-R3, R12} /* Increment nesting count. r3 holds the address of ulPortInterruptNesting - for future use. r1 holds the original ulPortInterruptNesting value for - future use. */ - LDR r3, ulPortInterruptNestingConst - LDR r1, [r3] - ADD r0, r1, #1 - STR r0, [r3] + * for future use. r1 holds the original ulPortInterruptNesting value for + * future use. */ + LDR R3, =ulPortInterruptNesting + LDR R1, [R3] + ADD R0, R1, #1 + STR R0, [R3] /* Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for - future use. */ - MOV r0, sp - AND r2, r0, #4 - SUB sp, sp, r2 + * future use. */ + MOV R0, SP + AND R2, R0, #4 + SUB SP, SP, R2 /* Call the interrupt handler. */ - PUSH {r0-r3, lr} - LDR r1, vApplicationIRQHandlerConst - BLX r1 - POP {r0-r3, lr} - ADD sp, sp, r2 + PUSH {R0-R3, LR} + BLX vApplicationIRQHandler + POP {R0-R3, LR} + ADD SP, SP, R2 + /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry. */ CPSID i DSB ISB /* Write to the EOI register. */ - LDR r0, ulICCEOIRConst - LDR r2, [r0] - STR r0, [r2] + LDR R0, =ulICCEOIR + LDR R2, [R0] + STR R0, [R2] /* Restore the old nesting count. */ - STR r1, [r3] + STR R1, [R3] /* A context switch is never performed if the nesting count is not 0. */ - CMP r1, #0 + CMP R1, #0 BNE exit_without_switch /* Did the interrupt request a context switch? r1 holds the address of - ulPortYieldRequired and r0 the value of ulPortYieldRequired for future - use. */ - LDR r1, ulPortYieldRequiredConst - LDR r0, [r1] - CMP r0, #0 + * ulPortYieldRequired and r0 the value of ulPortYieldRequired for future + * use. */ + LDR R1, =ulPortYieldRequired + LDR R0, [R1] + CMP R0, #0 BNE switch_before_exit exit_without_switch: /* No context switch. Restore used registers, LR_irq and SPSR before - returning. */ - POP {r0-r3, r12} + * returning. */ + POP {R0-R3, R12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR @@ -223,14 +405,14 @@ exit_without_switch: MOVS PC, LR switch_before_exit: - /* A context swtich is to be performed. Clear the context switch pending - flag. */ - MOV r0, #0 - STR r0, [r1] + /* A context switch is to be performed. Clear the context switch pending + * flag. */ + MOV R0, #0 + STR R0, [R1] /* Restore used registers, LR-irq and SPSR before saving the context - to the task stack. */ - POP {r0-r3, r12} + * to the task stack. */ + POP {R0-R3, R12} CPS #IRQ_MODE POP {LR} MSR SPSR_cxsf, LR @@ -238,23 +420,15 @@ switch_before_exit: portSAVE_CONTEXT /* Call the function that selects the new task to execute. - vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD - instructions, or 8 byte aligned stack allocated data. LR does not need - saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ - LDR R0, vTaskSwitchContextConst - BLX R0 + * vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD + * instructions, or 8 byte aligned stack allocated data. LR does not need + * saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ + BLX vTaskSwitchContext /* Restore the context of, and branch to, the task selected to execute - next. */ + * next. */ portRESTORE_CONTEXT -ulICCEOIRConst: .word ulICCEOIR -pxCurrentTCBConst: .word pxCurrentTCB -ulCriticalNestingConst: .word ulCriticalNesting -ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext -vTaskSwitchContextConst: .word vTaskSwitchContext -vApplicationIRQHandlerConst: .word vApplicationIRQHandler -ulPortInterruptNestingConst: .word ulPortInterruptNesting -ulPortYieldRequiredConst: .word ulPortYieldRequired +/*-----------------------------------------------------------*/ .end diff --git a/portable/GCC/ARM_CRx_No_GIC/portmacro.h b/portable/GCC/ARM_CRx_No_GIC/portmacro.h index d88a0fd05..b29bd9be1 100644 --- a/portable/GCC/ARM_CRx_No_GIC/portmacro.h +++ b/portable/GCC/ARM_CRx_No_GIC/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -59,7 +59,7 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef uint32_t TickType_t; -#define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#define portMAX_DELAY ( TickType_t ) 0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do * not need to be guarded with a critical section. */ @@ -88,47 +88,31 @@ typedef uint32_t TickType_t; } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) -#define portYIELD() \ - __asm volatile ( "SWI 0 \n" \ - "ISB " ::: "memory" ); +void vPortYield( void ); -/*----------------------------------------------------------- -* Critical section control -*----------------------------------------------------------*/ +#define portYIELD() vPortYield(); + +/*-----------------------------------------------------------*/ + +/* + * Critical section management. + */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); -extern uint32_t ulPortSetInterruptMask( void ); -extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); -extern void vPortInstallFreeRTOSVectorTable( void ); - -/* The I bit within the CPSR. */ -#define portINTERRUPT_ENABLE_BIT ( 1 << 7 ) +extern void vPortEnableInterrupts( void ); +extern void vPortDisableInterrupts( void ); +extern uint32_t ulPortSetInterruptMaskFromISR( void ); /* In the absence of a priority mask register, these functions and macros * globally enable and disable interrupts. */ -#define portENTER_CRITICAL() vPortEnterCritical(); -#define portEXIT_CRITICAL() vPortExitCritical(); -#define portENABLE_INTERRUPTS() __asm volatile ( "CPSIE i \n" ::: "memory" ); -#define portDISABLE_INTERRUPTS() \ - __asm volatile ( "CPSID i \n" \ - "DSB \n" \ - "ISB " ::: "memory" ); - -__attribute__( ( always_inline ) ) static __inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void ) -{ - volatile uint32_t ulCPSR; - - __asm volatile ( "MRS %0, CPSR" : "=r" ( ulCPSR )::"memory" ); - - ulCPSR &= portINTERRUPT_ENABLE_BIT; - portDISABLE_INTERRUPTS(); - return ulCPSR; -} - -#define portSET_INTERRUPT_MASK_FROM_ISR() portINLINE_SET_INTERRUPT_MASK_FROM_ISR() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) do { if( x == 0 ) portENABLE_INTERRUPTS( ); } while( 0 ) +#define portENTER_CRITICAL() vPortEnterCritical(); +#define portEXIT_CRITICAL() vPortExitCritical(); +#define portENABLE_INTERRUPTS() vPortEnableInterrupts(); +#define portDISABLE_INTERRUPTS() vPortDisableInterrupts(); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMaskFromISR(); +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) do { if( x == 0 ) portENABLE_INTERRUPTS(); } while( 0 ) /*-----------------------------------------------------------*/ @@ -148,9 +132,27 @@ __attribute__( ( always_inline ) ) static __inline uint32_t portINLINE_SET_INTER * handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); -/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() - * before any floating point instructions are executed. */ -void vPortTaskUsesFPU( void ); +/** + * @brief Returns the number of leading zeros in a 32 bit variable. + * + * @param[in] ulBitmap 32-Bit number to count leading zeros in. + * + * @return The number of leading zeros in ulBitmap. + */ +UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); + +/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are + * created without an FPU context and must call vPortTaskUsesFPU() to give + * themselves an FPU context before using any FPU instructions. If + * configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU + * context by default. */ +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) + void vPortTaskUsesFPU( void ); +#else + /* Each task has an FPU context already, so define this function as a + * no-op. */ + #define vPortTaskUsesFPU() +#endif #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) @@ -163,19 +165,15 @@ void vPortTaskUsesFPU( void ); #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 -/* Store/clear the ready priorities in a bit map. */ + /* Store, clear and get the ready priorities in a bit map. */ #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) - -/*-----------------------------------------------------------*/ - - #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) ) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #define portNOP() __asm volatile ( "NOP" ) -#define portINLINE __inline - +#define portINLINE __inline #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) /* *INDENT-OFF* */ diff --git a/portable/GCC/ATMega323/port.c b/portable/GCC/ATMega323/port.c index 6d71a6da3..ff80a8b81 100644 --- a/portable/GCC/ATMega323/port.c +++ b/portable/GCC/ATMega323/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ATMega323/portmacro.h b/portable/GCC/ATMega323/portmacro.h index 275468b4c..6ed5e4295 100644 --- a/portable/GCC/ATMega323/portmacro.h +++ b/portable/GCC/ATMega323/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/AVR32_UC3/exception.S b/portable/GCC/AVR32_UC3/exception.S index 9d46489ae..4e1b29703 100644 --- a/portable/GCC/AVR32_UC3/exception.S +++ b/portable/GCC/AVR32_UC3/exception.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * diff --git a/portable/GCC/AVR32_UC3/port.c b/portable/GCC/AVR32_UC3/port.c index 6e7257304..984ef56a0 100644 --- a/portable/GCC/AVR32_UC3/port.c +++ b/portable/GCC/AVR32_UC3/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * @@ -401,7 +401,7 @@ static void prvSetupTimerInterrupt( void ) #if ( configTICK_USE_TC == 1 ) volatile avr32_tc_t * tc = &AVR32_TC; - /* Options for waveform genration. */ + /* Options for waveform generation. */ tc_waveform_opt_t waveform_opt = { .channel = configTICK_TC_CHANNEL, /* Channel selection. */ diff --git a/portable/GCC/AVR32_UC3/portmacro.h b/portable/GCC/AVR32_UC3/portmacro.h index 521c46397..d96a629b5 100644 --- a/portable/GCC/AVR32_UC3/portmacro.h +++ b/portable/GCC/AVR32_UC3/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * diff --git a/portable/GCC/CORTUS_APS3/port.c b/portable/GCC/CORTUS_APS3/port.c index 30c3ca654..8ea06df16 100644 --- a/portable/GCC/CORTUS_APS3/port.c +++ b/portable/GCC/CORTUS_APS3/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/CORTUS_APS3/portmacro.h b/portable/GCC/CORTUS_APS3/portmacro.h index 91a18bc74..a18af0f6f 100644 --- a/portable/GCC/CORTUS_APS3/portmacro.h +++ b/portable/GCC/CORTUS_APS3/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ColdFire_V2/port.c b/portable/GCC/ColdFire_V2/port.c index f35126df8..e3bbb6b9e 100644 --- a/portable/GCC/ColdFire_V2/port.c +++ b/portable/GCC/ColdFire_V2/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ColdFire_V2/portasm.S b/portable/GCC/ColdFire_V2/portasm.S index a3c6aca05..4b746ca22 100644 --- a/portable/GCC/ColdFire_V2/portasm.S +++ b/portable/GCC/ColdFire_V2/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ColdFire_V2/portmacro.h b/portable/GCC/ColdFire_V2/portmacro.h index 1a1b618d0..95381ab36 100644 --- a/portable/GCC/ColdFire_V2/portmacro.h +++ b/portable/GCC/ColdFire_V2/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/H8S2329/port.c b/portable/GCC/H8S2329/port.c index 7aec16f6c..f8693b37b 100644 --- a/portable/GCC/H8S2329/port.c +++ b/portable/GCC/H8S2329/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/H8S2329/portmacro.h b/portable/GCC/H8S2329/portmacro.h index 4b4e1cdac..a954d4335 100644 --- a/portable/GCC/H8S2329/portmacro.h +++ b/portable/GCC/H8S2329/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/HCS12/port.c b/portable/GCC/HCS12/port.c index e53a74a38..4355a3f11 100644 --- a/portable/GCC/HCS12/port.c +++ b/portable/GCC/HCS12/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/HCS12/portmacro.h b/portable/GCC/HCS12/portmacro.h index 37034a036..4d02ad54e 100644 --- a/portable/GCC/HCS12/portmacro.h +++ b/portable/GCC/HCS12/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/IA32_flat/ISR_Support.h b/portable/GCC/IA32_flat/ISR_Support.h index cecd6a152..18e10bf91 100644 --- a/portable/GCC/IA32_flat/ISR_Support.h +++ b/portable/GCC/IA32_flat/ISR_Support.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -26,106 +26,103 @@ * */ -.extern ulTopOfSystemStack - .extern ulInterruptNesting + .extern ulTopOfSystemStack + .extern ulInterruptNesting /*-----------------------------------------------------------*/ - .macro portFREERTOS_INTERRUPT_ENTRY +.macro portFREERTOS_INTERRUPT_ENTRY -/* Save general purpose registers. */ -pusha + /* Save general purpose registers. */ + pusha -/* If ulInterruptNesting is zero the rest of the task context will need - * saving and a stack switch might be required. */ -movl ulInterruptNesting, % eax -test % eax, % eax -jne 2f + /* If ulInterruptNesting is zero the rest of the task context will need + saving and a stack switch might be required. */ + movl ulInterruptNesting, %eax + test %eax, %eax + jne 2f -/* Interrupts are not nested, so save the rest of the task context. */ - . + /* Interrupts are not nested, so save the rest of the task context. */ + .if configSUPPORT_FPU == 1 - if configSUPPORT_FPU == 1 + /* If the task has a buffer allocated to save the FPU context then + save the FPU context now. */ + movl pucPortTaskFPUContextBuffer, %eax + test %eax, %eax + je 1f + fnsave ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */ + fwait -/* If the task has a buffer allocated to save the FPU context then - * save the FPU context now. */ -movl pucPortTaskFPUContextBuffer, % eax -test % eax, % eax -je 1f -fnsave( % eax ) /* Save FLOP context into ucTempFPUBuffer array. */ -fwait + 1: + /* Save the address of the FPU context, if any. */ + push pucPortTaskFPUContextBuffer -1 : -/* Save the address of the FPU context, if any. */ -push pucPortTaskFPUContextBuffer + .endif /* configSUPPORT_FPU */ - .endif /* configSUPPORT_FPU */ + /* Find the TCB. */ + movl pxCurrentTCB, %eax -/* Find the TCB. */ -movl pxCurrentTCB, % eax + /* Stack location is first item in the TCB. */ + movl %esp, (%eax) -/* Stack location is first item in the TCB. */ - movl % esp, ( % eax ) + /* Switch stacks. */ + movl ulTopOfSystemStack, %esp + movl %esp, %ebp -/* Switch stacks. */ -movl ulTopOfSystemStack, % esp -movl % esp, % ebp + 2: + /* Increment nesting count. */ + add $1, ulInterruptNesting -2 : -/* Increment nesting count. */ -add $1, ulInterruptNesting - - .endm +.endm /*-----------------------------------------------------------*/ - .macro portINTERRUPT_EPILOGUE +.macro portINTERRUPT_EPILOGUE -cli -sub $1, ulInterruptNesting + cli + sub $1, ulInterruptNesting -/* If the nesting has unwound to zero. */ -movl ulInterruptNesting, % eax - test % eax, % eax - jne 2f + /* If the nesting has unwound to zero. */ + movl ulInterruptNesting, %eax + test %eax, %eax + jne 2f -/* If a yield was requested then select a new TCB now. */ -movl ulPortYieldPending, % eax - test % eax, % eax - je 1f -movl $0, ulPortYieldPending -call vTaskSwitchContext + /* If a yield was requested then select a new TCB now. */ + movl ulPortYieldPending, %eax + test %eax, %eax + je 1f + movl $0, ulPortYieldPending + call vTaskSwitchContext -1 : -/* Stack location is first item in the TCB. */ -movl pxCurrentTCB, % eax movl( % eax ), % esp + 1: + /* Stack location is first item in the TCB. */ + movl pxCurrentTCB, %eax + movl (%eax), %esp - . + .if configSUPPORT_FPU == 1 - if configSUPPORT_FPU == 1 + /* Restore address of task's FPU context buffer. */ + pop pucPortTaskFPUContextBuffer -/* Restore address of task's FPU context buffer. */ -pop pucPortTaskFPUContextBuffer + /* If the task has a buffer allocated in which its FPU context is saved, + then restore it now. */ + movl pucPortTaskFPUContextBuffer, %eax + test %eax, %eax + je 1f + frstor ( %eax ) + 1: + .endif -/* If the task has a buffer allocated in which its FPU context is saved, - * then restore it now. */ -movl pucPortTaskFPUContextBuffer, % eax -test % eax, % eax -je 1f -frstor( % eax ) -1 : -.endif + 2: + popa -2 : -popa - - .endm +.endm /*-----------------------------------------------------------*/ - .macro portFREERTOS_INTERRUPT_EXIT +.macro portFREERTOS_INTERRUPT_EXIT -portINTERRUPT_EPILOGUE -/* EOI. */ -movl $0x00, ( 0xFEE000B0 ) -iret + portINTERRUPT_EPILOGUE + /* EOI. */ + movl $0x00, (0xFEE000B0) + iret - .endm +.endm diff --git a/portable/GCC/IA32_flat/port.c b/portable/GCC/IA32_flat/port.c index da1559416..682cce951 100644 --- a/portable/GCC/IA32_flat/port.c +++ b/portable/GCC/IA32_flat/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -666,11 +666,13 @@ static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber ) /* In use by FreeRTOS. */ xReturn = pdFAIL; } +#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 ) else if( xInterruptHandlerTable[ ulVectorNumber ] != NULL ) { /* Already in use by the application. */ xReturn = pdFAIL; } +#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */ else { xReturn = pdPASS; diff --git a/portable/GCC/IA32_flat/portASM.S b/portable/GCC/IA32_flat/portASM.S index 4dac1af0b..c01b32bce 100644 --- a/portable/GCC/IA32_flat/portASM.S +++ b/portable/GCC/IA32_flat/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/IA32_flat/portmacro.h b/portable/GCC/IA32_flat/portmacro.h index fd07ee71d..085250e04 100644 --- a/portable/GCC/IA32_flat/portmacro.h +++ b/portable/GCC/IA32_flat/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MSP430F449/port.c b/portable/GCC/MSP430F449/port.c index 0b41665ce..48a1a7921 100644 --- a/portable/GCC/MSP430F449/port.c +++ b/portable/GCC/MSP430F449/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -183,16 +183,23 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xbbbb; pxTopOfStack--; +#ifdef __MSPGCC__ *pxTopOfStack = ( StackType_t ) 0xcccc; +#else + /* The MSP430 EABI expects the function parameter in R12. */ + *pxTopOfStack = ( StackType_t ) pvParameters; +#endif pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xdddd; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0xeeee; pxTopOfStack--; - - /* When the task starts is will expect to find the function parameter in - * R15. */ +#ifdef __MSPGCC__ + /* The mspgcc ABI expects the function parameter in R15. */ *pxTopOfStack = ( StackType_t ) pvParameters; +#else + *pxTopOfStack = ( StackType_t ) 0xffff; +#endif pxTopOfStack--; /* The code generated by the mspgcc compiler does not maintain separate @@ -296,8 +303,8 @@ static void prvSetupTimerInterrupt( void ) * the context is saved at the start of vPortYieldFromTick(). The tick * count is incremented after the context is saved. */ - interrupt( TIMERA0_VECTOR ) prvTickISR( void ) __attribute__( ( naked ) ); - interrupt( TIMERA0_VECTOR ) prvTickISR( void ) + interrupt( TIMERA0_VECTOR ) void prvTickISR( void ) __attribute__( ( naked ) ); + interrupt( TIMERA0_VECTOR ) void prvTickISR( void ) { /* Save the context of the interrupted task. */ portSAVE_CONTEXT(); @@ -320,8 +327,8 @@ static void prvSetupTimerInterrupt( void ) * tick count. We don't need to switch context, this can only be done by * manual calls to taskYIELD(); */ - interrupt( TIMERA0_VECTOR ) prvTickISR( void ); - interrupt( TIMERA0_VECTOR ) prvTickISR( void ) + interrupt( TIMERA0_VECTOR ) void prvTickISR( void ); + interrupt( TIMERA0_VECTOR ) void prvTickISR( void ) { xTaskIncrementTick(); } diff --git a/portable/GCC/MSP430F449/portmacro.h b/portable/GCC/MSP430F449/portmacro.h index 445279f5c..de2014683 100644 --- a/portable/GCC/MSP430F449/portmacro.h +++ b/portable/GCC/MSP430F449/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -53,6 +53,7 @@ #define portSHORT int #define portSTACK_TYPE uint16_t #define portBASE_TYPE short +#define portPOINTER_SIZE_TYPE uint16_t typedef portSTACK_TYPE StackType_t; typedef short BaseType_t; @@ -118,6 +119,11 @@ extern void vPortYield( void ) __attribute__( ( naked ) ); #define portBYTE_ALIGNMENT 2 #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + +/* GCC used to define these but doesn't any more */ +#define interrupt(vector) __attribute__((__interrupt__(vector))) +#define wakeup __attribute__((__wakeup__)) + /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ diff --git a/portable/GCC/MicroBlaze/port.c b/portable/GCC/MicroBlaze/port.c index 2051e3e44..fb8b410be 100644 --- a/portable/GCC/MicroBlaze/port.c +++ b/portable/GCC/MicroBlaze/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MicroBlaze/portasm.s b/portable/GCC/MicroBlaze/portasm.s index 344914893..b9c1dc8b3 100644 --- a/portable/GCC/MicroBlaze/portasm.s +++ b/portable/GCC/MicroBlaze/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MicroBlaze/portmacro.h b/portable/GCC/MicroBlaze/portmacro.h index 8ddeb0ed0..a81e07cde 100644 --- a/portable/GCC/MicroBlaze/portmacro.h +++ b/portable/GCC/MicroBlaze/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MicroBlazeV8/port.c b/portable/GCC/MicroBlazeV8/port.c index 5dced2b93..1557af645 100644 --- a/portable/GCC/MicroBlazeV8/port.c +++ b/portable/GCC/MicroBlazeV8/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MicroBlazeV8/port_exceptions.c b/portable/GCC/MicroBlazeV8/port_exceptions.c index e2347732d..281a328b4 100644 --- a/portable/GCC/MicroBlazeV8/port_exceptions.c +++ b/portable/GCC/MicroBlazeV8/port_exceptions.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MicroBlazeV8/portasm.S b/portable/GCC/MicroBlazeV8/portasm.S index d0e20515d..36829767d 100644 --- a/portable/GCC/MicroBlazeV8/portasm.S +++ b/portable/GCC/MicroBlazeV8/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MicroBlazeV8/portmacro.h b/portable/GCC/MicroBlazeV8/portmacro.h index 7606850bc..d23214ea4 100644 --- a/portable/GCC/MicroBlazeV8/portmacro.h +++ b/portable/GCC/MicroBlazeV8/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/MicroBlazeV9/port.c b/portable/GCC/MicroBlazeV9/port.c index fd5de1527..7a94ece00 100644 --- a/portable/GCC/MicroBlazeV9/port.c +++ b/portable/GCC/MicroBlazeV9/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -42,6 +42,7 @@ #include #include #include +#include /* Tasks are started with a critical section nesting of 0 - however, prior to * the scheduler being commenced interrupts should not be enabled, so the critical @@ -58,6 +59,13 @@ * given to the FSR register when the initial context is set up for a task being * created. */ #define portINITIAL_FSR ( 0U ) +/* + * Global counter used for calculation of run time statistics of tasks. + * Defined only when the relevant option is turned on + */ +#if (configGENERATE_RUN_TIME_STATS==1) + volatile uint32_t ulHighFrequencyTimerTicks; +#endif /*-----------------------------------------------------------*/ @@ -116,10 +124,11 @@ static XIntc xInterruptControllerInstance; void * pvParameters ) #endif { - extern void * _SDA2_BASE_; - extern void * _SDA_BASE_; - const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_; - const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_; + extern void *_SDA2_BASE_; + extern void *_SDA_BASE_; + const UINTPTR ulR2 = ( UINTPTR ) &_SDA2_BASE_; + const UINTPTR ulR13 = ( UINTPTR ) &_SDA_BASE_; + extern void _start1( void ); /* Place a few bytes of known values on the bottom of the stack. @@ -255,8 +264,8 @@ static XIntc xInterruptControllerInstance; BaseType_t xPortStartScheduler( void ) { - extern void( vPortStartFirstTask )( void ); - extern uint32_t _stack[]; + extern void ( vPortStartFirstTask )( void ); + extern UINTPTR _stack[]; /* Setup the hardware to generate the tick. Interrupts are disabled when * this function is called. @@ -270,7 +279,7 @@ BaseType_t xPortStartScheduler( void ) vApplicationSetupTimerInterrupt(); /* Reuse the stack from main() as the stack for the interrupts/exceptions. */ - pulISRStack = ( uint32_t * ) _stack; + pulISRStack = ( UINTPTR * ) _stack; /* Ensure there is enough space for the functions called from the interrupt * service routines to write back into the stack frame of the caller. */ @@ -304,13 +313,18 @@ void vPortYield( void ) * not interrupted by the tick ISR. It is not a problem to do this as * each task maintains its own interrupt status. */ portENTER_CRITICAL(); - { - /* Jump directly to the yield function to ensure there is no - * compiler generated prologue code. */ - asm volatile ( "bralid r14, VPortYieldASM \n\t" \ - "or r0, r0, r0 \n\t" ); - } - portEXIT_CRITICAL(); + { + /* Jump directly to the yield function to ensure there is no + * compiler generated prologue code. */ + #ifdef __arch64__ + asm volatile ( "brealid r14, VPortYieldASM \n\t" \ + "or r0, r0, r0 \n\t" ); + #else + asm volatile ( "bralid r14, VPortYieldASM \n\t" \ + "or r0, r0, r0 \n\t" ); + #endif + } + portEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ @@ -434,22 +448,34 @@ void vPortTickISR( void * pvUnused ) { extern void vApplicationClearTimerInterrupt( void ); - /* Ensure the unused parameter does not generate a compiler warning. */ - ( void ) pvUnused; + /* Ensure the unused parameter does not generate a compiler warning. */ + ( void ) pvUnused; - /* This port uses an application defined callback function to clear the tick - * interrupt because the kernel will run on lots of different MicroBlaze and - * FPGA configurations - not all of which will have the same timer peripherals - * defined or available. An example definition of - * vApplicationClearTimerInterrupt() is provided in the official demo - * application that accompanies this port. */ - vApplicationClearTimerInterrupt(); - - /* Increment the RTOS tick - this might cause a task to unblock. */ - if( xTaskIncrementTick() != pdFALSE ) + /* The Xilinx implementation of generating run time task stats uses the same timer used for generating + * FreeRTOS ticks. In case user decides to generate run time stats the tick handler is called more + * frequently (10 times faster). The timer ick handler uses logic to handle the same. It handles + * the FreeRTOS tick once per 10 interrupts. + * For handling generation of run time stats, it increments a pre-defined counter every time the + * interrupt handler executes. */ +#if (configGENERATE_RUN_TIME_STATS == 1) + ulHighFrequencyTimerTicks++; + if (!(ulHighFrequencyTimerTicks % 10)) +#endif { - /* Force vTaskSwitchContext() to be called as the interrupt exits. */ - ulTaskSwitchRequested = 1; + /* This port uses an application defined callback function to clear the tick + * interrupt because the kernel will run on lots of different MicroBlaze and + * FPGA configurations - not all of which will have the same timer peripherals + * defined or available. An example definition of + * vApplicationClearTimerInterrupt() is provided in the official demo + * application that accompanies this port. */ + vApplicationClearTimerInterrupt(); + + /* Increment the RTOS tick - this might cause a task to unblock. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Force vTaskSwitchContext() to be called as the interrupt exits. */ + ulTaskSwitchRequested = 1; + } } } /*-----------------------------------------------------------*/ @@ -495,4 +521,25 @@ static int32_t prvInitialiseInterruptController( void ) return lStatus; } + +#if( configGENERATE_RUN_TIME_STATS == 1 ) +/* + * For Xilinx implementation this is a dummy function that does a redundant operation + * of zeroing out the global counter. + * It is called by FreeRTOS kernel. + */ +void xCONFIGURE_TIMER_FOR_RUN_TIME_STATS (void) +{ + ulHighFrequencyTimerTicks = 0; +} +/* + * For Xilinx implementation this function returns the global counter used for + * run time task stats calculation. + * It is called by FreeRTOS kernel task handling logic. + */ +uint32_t xGET_RUN_TIME_COUNTER_VALUE (void) +{ + return ulHighFrequencyTimerTicks; +} +#endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/MicroBlazeV9/port_exceptions.c b/portable/GCC/MicroBlazeV9/port_exceptions.c index e2347732d..21dd28844 100644 --- a/portable/GCC/MicroBlazeV9/port_exceptions.c +++ b/portable/GCC/MicroBlazeV9/port_exceptions.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -67,7 +67,7 @@ /* This variable is set in the exception entry code, before * vPortExceptionHandler is called. */ - uint32_t * pulStackPointerOnFunctionEntry = NULL; + UINTPTR *pulStackPointerOnFunctionEntry = NULL; /* This is the structure that is filled with the MicroBlaze context as it * existed immediately prior to the exception occurrence. A pointer to this @@ -80,7 +80,6 @@ * in portasm.S. */ void vPortExceptionHandler( void * pvExceptionID ); extern void vPortExceptionHandlerEntry( void * pvExceptionID ); - /*-----------------------------------------------------------*/ /* vApplicationExceptionRegisterDump() is a callback function that the @@ -149,7 +148,7 @@ xRegisterDump.ulR29 = mfgpr( R29 ); xRegisterDump.ulR30 = mfgpr( R30 ); xRegisterDump.ulR31 = mfgpr( R31 ); - xRegisterDump.ulR1_SP = ( ( uint32_t ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE; + xRegisterDump.ulR1_SP = ( ( UINTPTR ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE; xRegisterDump.ulEAR = mfear(); xRegisterDump.ulESR = mfesr(); xRegisterDump.ulEDR = mfedr(); diff --git a/portable/GCC/MicroBlazeV9/portasm.S b/portable/GCC/MicroBlazeV9/portasm.S index 2114d00e8..7480e76ed 100644 --- a/portable/GCC/MicroBlazeV9/portasm.S +++ b/portable/GCC/MicroBlazeV9/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -33,63 +33,97 @@ #include "microblaze_exceptions_g.h" #include "xparameters.h" +#include "microblaze_instructions.h" +/* The context is oversized to allow functions called from the ISR to write +back into the caller stack. */ +#if defined (__arch64__) +#if( XPAR_MICROBLAZE_USE_FPU != 0 ) + #define portCONTEXT_SIZE 272 + #define portMINUS_CONTEXT_SIZE -272 +#else + #define portCONTEXT_SIZE 264 + #define portMINUS_CONTEXT_SIZE -264 +#endif +#else +#if( XPAR_MICROBLAZE_USE_FPU != 0 ) + #define portCONTEXT_SIZE 136 + #define portMINUS_CONTEXT_SIZE -136 +#else + #define portCONTEXT_SIZE 132 + #define portMINUS_CONTEXT_SIZE -132 +#endif +#endif + /* Offsets from the stack pointer at which saved registers are placed. */ -#define portR31_OFFSET 4 -#define portR30_OFFSET 8 -#define portR29_OFFSET 12 -#define portR28_OFFSET 16 -#define portR27_OFFSET 20 -#define portR26_OFFSET 24 -#define portR25_OFFSET 28 -#define portR24_OFFSET 32 -#define portR23_OFFSET 36 -#define portR22_OFFSET 40 -#define portR21_OFFSET 44 -#define portR20_OFFSET 48 -#define portR19_OFFSET 52 -#define portR18_OFFSET 56 -#define portR17_OFFSET 60 -#define portR16_OFFSET 64 -#define portR15_OFFSET 68 -#define portR14_OFFSET 72 -#define portR13_OFFSET 76 -#define portR12_OFFSET 80 -#define portR11_OFFSET 84 -#define portR10_OFFSET 88 -#define portR9_OFFSET 92 -#define portR8_OFFSET 96 -#define portR7_OFFSET 100 -#define portR6_OFFSET 104 -#define portR5_OFFSET 108 -#define portR4_OFFSET 112 -#define portR3_OFFSET 116 -#define portR2_OFFSET 120 +#if defined (__arch64__) +#define portR31_OFFSET 8 +#define portR30_OFFSET 16 +#define portR29_OFFSET 24 +#define portR28_OFFSET 32 +#define portR27_OFFSET 40 +#define portR26_OFFSET 48 +#define portR25_OFFSET 56 +#define portR24_OFFSET 64 +#define portR23_OFFSET 72 +#define portR22_OFFSET 80 +#define portR21_OFFSET 88 +#define portR20_OFFSET 96 +#define portR19_OFFSET 104 +#define portR18_OFFSET 112 +#define portR17_OFFSET 120 +#define portR16_OFFSET 128 +#define portR15_OFFSET 136 +#define portR14_OFFSET 144 +#define portR13_OFFSET 152 +#define portR12_OFFSET 160 +#define portR11_OFFSET 168 +#define portR10_OFFSET 176 +#define portR9_OFFSET 184 +#define portR8_OFFSET 192 +#define portR7_OFFSET 200 +#define portR6_OFFSET 208 +#define portR5_OFFSET 216 +#define portR4_OFFSET 224 +#define portR3_OFFSET 232 +#define portR2_OFFSET 240 +#define portCRITICAL_NESTING_OFFSET 248 +#define portMSR_OFFSET 256 +#define portFSR_OFFSET 264 +#else +#define portR31_OFFSET 4 +#define portR30_OFFSET 8 +#define portR29_OFFSET 12 +#define portR28_OFFSET 16 +#define portR27_OFFSET 20 +#define portR26_OFFSET 24 +#define portR25_OFFSET 28 +#define portR24_OFFSET 32 +#define portR23_OFFSET 36 +#define portR22_OFFSET 40 +#define portR21_OFFSET 44 +#define portR20_OFFSET 48 +#define portR19_OFFSET 52 +#define portR18_OFFSET 56 +#define portR17_OFFSET 60 +#define portR16_OFFSET 64 +#define portR15_OFFSET 68 +#define portR14_OFFSET 72 +#define portR13_OFFSET 76 +#define portR12_OFFSET 80 +#define portR11_OFFSET 84 +#define portR10_OFFSET 88 +#define portR9_OFFSET 92 +#define portR8_OFFSET 96 +#define portR7_OFFSET 100 +#define portR6_OFFSET 104 +#define portR5_OFFSET 108 +#define portR4_OFFSET 112 +#define portR3_OFFSET 116 +#define portR2_OFFSET 120 #define portCRITICAL_NESTING_OFFSET 124 #define portMSR_OFFSET 128 +#define portFSR_OFFSET 132 -#if( XPAR_MICROBLAZE_USE_FPU != 0 ) - #define portFSR_OFFSET 132 - #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) - #define portSLR_OFFSET 136 - #define portSHR_OFFSET 140 - - #define portCONTEXT_SIZE 144 - #define portMINUS_CONTEXT_SIZE -144 - #else - #define portCONTEXT_SIZE 136 - #define portMINUS_CONTEXT_SIZE -136 - #endif -#else - #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) - #define portSLR_OFFSET 132 - #define portSHR_OFFSET 136 - - #define portCONTEXT_SIZE 140 - #define portMINUS_CONTEXT_SIZE -140 - #else - #define portCONTEXT_SIZE 132 - #define portMINUS_CONTEXT_SIZE -132 - #endif #endif .extern pxCurrentTCB @@ -109,54 +143,54 @@ .macro portSAVE_CONTEXT - /* Make room for the context on the stack. */ - addik r1, r1, portMINUS_CONTEXT_SIZE + /* Make room for the context on the stack. */ + ADDLIK r1, r1, portMINUS_CONTEXT_SIZE - /* Stack general registers. */ - swi r31, r1, portR31_OFFSET - swi r30, r1, portR30_OFFSET - swi r29, r1, portR29_OFFSET - swi r28, r1, portR28_OFFSET - swi r27, r1, portR27_OFFSET - swi r26, r1, portR26_OFFSET - swi r25, r1, portR25_OFFSET - swi r24, r1, portR24_OFFSET - swi r23, r1, portR23_OFFSET - swi r22, r1, portR22_OFFSET - swi r21, r1, portR21_OFFSET - swi r20, r1, portR20_OFFSET - swi r19, r1, portR19_OFFSET - swi r18, r1, portR18_OFFSET - swi r17, r1, portR17_OFFSET - swi r16, r1, portR16_OFFSET - swi r15, r1, portR15_OFFSET - /* R14 is saved later as it needs adjustment if a yield is performed. */ - swi r13, r1, portR13_OFFSET - swi r12, r1, portR12_OFFSET - swi r11, r1, portR11_OFFSET - swi r10, r1, portR10_OFFSET - swi r9, r1, portR9_OFFSET - swi r8, r1, portR8_OFFSET - swi r7, r1, portR7_OFFSET - swi r6, r1, portR6_OFFSET - swi r5, r1, portR5_OFFSET - swi r4, r1, portR4_OFFSET - swi r3, r1, portR3_OFFSET - swi r2, r1, portR2_OFFSET + /* Stack general registers. */ + SI r31, r1, portR31_OFFSET + SI r30, r1, portR30_OFFSET + SI r29, r1, portR29_OFFSET + SI r28, r1, portR28_OFFSET + SI r27, r1, portR27_OFFSET + SI r26, r1, portR26_OFFSET + SI r25, r1, portR25_OFFSET + SI r24, r1, portR24_OFFSET + SI r23, r1, portR23_OFFSET + SI r22, r1, portR22_OFFSET + SI r21, r1, portR21_OFFSET + SI r20, r1, portR20_OFFSET + SI r19, r1, portR19_OFFSET + SI r18, r1, portR18_OFFSET + SI r17, r1, portR17_OFFSET + SI r16, r1, portR16_OFFSET + SI r15, r1, portR15_OFFSET + /* R14 is saved later as it needs adjustment if a yield is performed. */ + SI r13, r1, portR13_OFFSET + SI r12, r1, portR12_OFFSET + SI r11, r1, portR11_OFFSET + SI r10, r1, portR10_OFFSET + SI r9, r1, portR9_OFFSET + SI r8, r1, portR8_OFFSET + SI r7, r1, portR7_OFFSET + SI r6, r1, portR6_OFFSET + SI r5, r1, portR5_OFFSET + SI r4, r1, portR4_OFFSET + SI r3, r1, portR3_OFFSET + SI r2, r1, portR2_OFFSET - /* Stack the critical section nesting value. */ - lwi r18, r0, uxCriticalNesting - swi r18, r1, portCRITICAL_NESTING_OFFSET + /* Stack the critical section nesting value. */ + LI r18, r0, uxCriticalNesting + SI r18, r1, portCRITICAL_NESTING_OFFSET - /* Stack MSR. */ - mfs r18, rmsr - swi r18, r1, portMSR_OFFSET + /* Stack MSR. */ + mfs r18, rmsr + SI r18, r1, portMSR_OFFSET - #if( XPAR_MICROBLAZE_USE_FPU != 0 ) - /* Stack FSR. */ - mfs r18, rfsr - swi r18, r1, portFSR_OFFSET - #endif + #if( XPAR_MICROBLAZE_USE_FPU != 0 ) + /* Stack FSR. */ + mfs r18, rfsr + SI r18, r1, portFSR_OFFSET + #endif #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) /* Save the stack limits */ @@ -166,17 +200,17 @@ swi r18, r1, portSHR_OFFSET #endif - /* Save the top of stack value to the TCB. */ - lwi r3, r0, pxCurrentTCB - sw r1, r0, r3 + /* Save the top of stack value to the TCB. */ + LI r3, r0, pxCurrentTCB + STORE r1, r0, r3 .endm .macro portRESTORE_CONTEXT - /* Load the top of stack value from the TCB. */ - lwi r18, r0, pxCurrentTCB - lw r1, r0, r18 + /* Load the top of stack value from the TCB. */ + LI r18, r0, pxCurrentTCB + LOAD r1, r0, r18 #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) /* Restore the stack limits -- must not load from r1 (Stack Pointer) @@ -189,101 +223,112 @@ mts rshr, r12 #endif - /* Restore the general registers. */ - lwi r31, r1, portR31_OFFSET - lwi r30, r1, portR30_OFFSET - lwi r29, r1, portR29_OFFSET - lwi r28, r1, portR28_OFFSET - lwi r27, r1, portR27_OFFSET - lwi r26, r1, portR26_OFFSET - lwi r25, r1, portR25_OFFSET - lwi r24, r1, portR24_OFFSET - lwi r23, r1, portR23_OFFSET - lwi r22, r1, portR22_OFFSET - lwi r21, r1, portR21_OFFSET - lwi r20, r1, portR20_OFFSET - lwi r19, r1, portR19_OFFSET - lwi r17, r1, portR17_OFFSET - lwi r16, r1, portR16_OFFSET - lwi r15, r1, portR15_OFFSET - lwi r14, r1, portR14_OFFSET - lwi r13, r1, portR13_OFFSET - lwi r12, r1, portR12_OFFSET - lwi r11, r1, portR11_OFFSET - lwi r10, r1, portR10_OFFSET - lwi r9, r1, portR9_OFFSET - lwi r8, r1, portR8_OFFSET - lwi r7, r1, portR7_OFFSET - lwi r6, r1, portR6_OFFSET - lwi r5, r1, portR5_OFFSET - lwi r4, r1, portR4_OFFSET - lwi r3, r1, portR3_OFFSET - lwi r2, r1, portR2_OFFSET + /* Restore the general registers. */ + LI r31, r1, portR31_OFFSET + LI r30, r1, portR30_OFFSET + LI r29, r1, portR29_OFFSET + LI r28, r1, portR28_OFFSET + LI r27, r1, portR27_OFFSET + LI r26, r1, portR26_OFFSET + LI r25, r1, portR25_OFFSET + LI r24, r1, portR24_OFFSET + LI r23, r1, portR23_OFFSET + LI r22, r1, portR22_OFFSET + LI r21, r1, portR21_OFFSET + LI r20, r1, portR20_OFFSET + LI r19, r1, portR19_OFFSET + LI r17, r1, portR17_OFFSET + LI r16, r1, portR16_OFFSET + LI r15, r1, portR15_OFFSET + LI r14, r1, portR14_OFFSET + LI r13, r1, portR13_OFFSET + LI r12, r1, portR12_OFFSET + LI r11, r1, portR11_OFFSET + LI r10, r1, portR10_OFFSET + LI r9, r1, portR9_OFFSET + LI r8, r1, portR8_OFFSET + LI r7, r1, portR7_OFFSET + LI r6, r1, portR6_OFFSET + LI r5, r1, portR5_OFFSET + LI r4, r1, portR4_OFFSET + LI r3, r1, portR3_OFFSET + LI r2, r1, portR2_OFFSET - /* Reload the rmsr from the stack. */ - lwi r18, r1, portMSR_OFFSET - mts rmsr, r18 + /* Reload the rmsr from the stack. */ + LI r18, r1, portMSR_OFFSET + mts rmsr, r18 - #if( XPAR_MICROBLAZE_USE_FPU != 0 ) - /* Reload the FSR from the stack. */ - lwi r18, r1, portFSR_OFFSET - mts rfsr, r18 - #endif + #if( XPAR_MICROBLAZE_USE_FPU != 0 ) + /* Reload the FSR from the stack. */ + LI r18, r1, portFSR_OFFSET + mts rfsr, r18 + #endif - /* Load the critical nesting value. */ - lwi r18, r1, portCRITICAL_NESTING_OFFSET - swi r18, r0, uxCriticalNesting + /* Load the critical nesting value. */ + LI r18, r1, portCRITICAL_NESTING_OFFSET + SI r18, r0, uxCriticalNesting - /* Test the critical nesting value. If it is non zero then the task last - exited the running state using a yield. If it is zero, then the task - last exited the running state through an interrupt. */ - xori r18, r18, 0 - bnei r18, exit_from_yield + /* Test the critical nesting value. If it is non zero then the task last + exited the running state using a yield. If it is zero, then the task + last exited the running state through an interrupt. */ + XORI r18, r18, 0 + BNEI r18, exit_from_yield - /* r18 was being used as a temporary. Now restore its true value from the - stack. */ - lwi r18, r1, portR18_OFFSET + /* r18 was being used as a temporary. Now restore its true value from the + stack. */ + LI r18, r1, portR18_OFFSET - /* Remove the stack frame. */ - addik r1, r1, portCONTEXT_SIZE + /* Remove the stack frame. */ + ADDLIK r1, r1, portCONTEXT_SIZE - /* Return using rtid so interrupts are re-enabled as this function is - exited. */ - rtid r14, 0 - or r0, r0, r0 + /* Return using rtid so interrupts are re-enabled as this function is + exited. */ + rtid r14, 0 + OR r0, r0, r0 - .endm + .endm /* This function is used to exit portRESTORE_CONTEXT() if the task being returned to last left the Running state by calling taskYIELD() (rather than being preempted by an interrupt). */ - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + exit_from_yield: - /* r18 was being used as a temporary. Now restore its true value from the - stack. */ - lwi r18, r1, portR18_OFFSET + /* r18 was being used as a temporary. Now restore its true value from the + stack. */ + LI r18, r1, portR18_OFFSET - /* Remove the stack frame. */ - addik r1, r1, portCONTEXT_SIZE + /* Remove the stack frame. */ + ADDLIK r1, r1, portCONTEXT_SIZE - /* Return to the task. */ - rtsd r14, 0 - or r0, r0, r0 + /* Return to the task. */ + rtsd r14, 0 + OR r0, r0, r0 - .text - .align 4 + .text + +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + _interrupt_handler: portSAVE_CONTEXT - /* Stack the return address. */ - swi r14, r1, portR14_OFFSET + /* Stack the return address. */ + SI r14, r1, portR14_OFFSET - /* Switch to the ISR stack. */ - lwi r1, r0, pulISRStack + /* Switch to the ISR stack. */ + LI r1, r0, pulISRStack #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) ori r18, r0, _stack_end @@ -292,29 +337,29 @@ _interrupt_handler: mts rshr, r18 #endif - /* The parameter to the interrupt handler. */ - ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE + /* The parameter to the interrupt handler. */ + ORI r5, r0, configINTERRUPT_CONTROLLER_TO_USE - /* Execute any pending interrupts. */ - bralid r15, XIntc_DeviceInterruptHandler - or r0, r0, r0 + /* Execute any pending interrupts. */ + BRALID r15, XIntc_DeviceInterruptHandler + OR r0, r0, r0 - /* See if a new task should be selected to execute. */ - lwi r18, r0, ulTaskSwitchRequested - or r18, r18, r0 + /* See if a new task should be selected to execute. */ + LI r18, r0, ulTaskSwitchRequested + OR r18, r18, r0 - /* If ulTaskSwitchRequested is already zero, then jump straight to - restoring the task that is already in the Running state. */ - beqi r18, task_switch_not_requested + /* If ulTaskSwitchRequested is already zero, then jump straight to + restoring the task that is already in the Running state. */ + BEQI r18, task_switch_not_requested - /* Set ulTaskSwitchRequested back to zero as a task switch is about to be - performed. */ - swi r0, r0, ulTaskSwitchRequested + /* Set ulTaskSwitchRequested back to zero as a task switch is about to be + performed. */ + SI r0, r0, ulTaskSwitchRequested - /* ulTaskSwitchRequested was not 0 when tested. Select the next task to - execute. */ - bralid r15, vTaskSwitchContext - or r0, r0, r0 + /* ulTaskSwitchRequested was not 0 when tested. Select the next task to + execute. */ + BRALID r15, vTaskSwitchContext + OR r0, r0, r0 task_switch_not_requested: @@ -322,19 +367,24 @@ task_switch_not_requested: portRESTORE_CONTEXT - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + VPortYieldASM: portSAVE_CONTEXT - /* Modify the return address so a return is done to the instruction after - the call to VPortYieldASM. */ - addi r14, r14, 8 - swi r14, r1, portR14_OFFSET + /* Modify the return address so a return is done to the instruction after + the call to VPortYieldASM. */ + ADDI r14, r14, 8 + SI r14, r1, portR14_OFFSET - /* Switch to use the ISR stack. */ - lwi r1, r0, pulISRStack + /* Switch to use the ISR stack. */ + LI r1, r0, pulISRStack #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) ori r18, r0, _stack_end @@ -343,15 +393,20 @@ VPortYieldASM: mts rshr, r18 #endif - /* Select the next task to execute. */ - bralid r15, vTaskSwitchContext - or r0, r0, r0 + /* Select the next task to execute. */ + BRALID r15, vTaskSwitchContext + OR r0, r0, r0 /* Restore the context of the next task scheduled to execute. */ portRESTORE_CONTEXT - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + vPortStartFirstTask: portRESTORE_CONTEXT @@ -360,14 +415,19 @@ vPortStartFirstTask: #if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + vPortExceptionHandlerEntry: - /* Take a copy of the stack pointer before vPortExecptionHandler is called, - storing its value prior to the function stack frame being created. */ - swi r1, r0, pulStackPointerOnFunctionEntry - bralid r15, vPortExceptionHandler - or r0, r0, r0 + /* Take a copy of the stack pointer before vPortExecptionHandler is called, + storing its value prior to the function stack frame being created. */ + SI r1, r0, pulStackPointerOnFunctionEntry + BRALID r15, vPortExceptionHandler + OR r0, r0, r0 #endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */ diff --git a/portable/GCC/MicroBlazeV9/portmacro.h b/portable/GCC/MicroBlazeV9/portmacro.h index ccf98ed4c..1fb9c8259 100644 --- a/portable/GCC/MicroBlazeV9/portmacro.h +++ b/portable/GCC/MicroBlazeV9/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,20 +50,26 @@ */ /* Type definitions. */ -#define portCHAR char -#define portFLOAT float -#define portDOUBLE double -#define portLONG long -#define portSHORT short -#define portSTACK_TYPE uint32_t -#define portBASE_TYPE long +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#ifdef __arch64__ + #define portSTACK_TYPE size_t + typedef uint64_t UBaseType_t; +#else + #define portSTACK_TYPE uint32_t + typedef unsigned long UBaseType_t; +#endif +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; -typedef portSTACK_TYPE StackType_t; -typedef long BaseType_t; -typedef unsigned long UBaseType_t; #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; + typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; @@ -155,10 +161,14 @@ extern volatile uint32_t ulTaskSwitchRequested; /*-----------------------------------------------------------*/ /* Hardware specifics. */ -#define portBYTE_ALIGNMENT 4 -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portNOP() asm volatile ( "NOP" ) +#ifdef __arch64__ + #define portBYTE_ALIGNMENT 8 +#else + #define portBYTE_ALIGNMENT 4 +#endif +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portNOP() asm volatile ( "NOP" ) #define portMEMORY_BARRIER() asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ @@ -179,43 +189,43 @@ typedef struct PORT_REGISTER_DUMP { /* The following structure members hold the values of the MicroBlaze * registers at the time the exception was raised. */ - uint32_t ulR1_SP; - uint32_t ulR2_small_data_area; - uint32_t ulR3; - uint32_t ulR4; - uint32_t ulR5; - uint32_t ulR6; - uint32_t ulR7; - uint32_t ulR8; - uint32_t ulR9; - uint32_t ulR10; - uint32_t ulR11; - uint32_t ulR12; - uint32_t ulR13_read_write_small_data_area; - uint32_t ulR14_return_address_from_interrupt; - uint32_t ulR15_return_address_from_subroutine; - uint32_t ulR16_return_address_from_trap; - uint32_t ulR17_return_address_from_exceptions; /* The exception entry code will copy the BTR into R17 if the exception occurred in the delay slot of a branch instruction. */ - uint32_t ulR18; - uint32_t ulR19; - uint32_t ulR20; - uint32_t ulR21; - uint32_t ulR22; - uint32_t ulR23; - uint32_t ulR24; - uint32_t ulR25; - uint32_t ulR26; - uint32_t ulR27; - uint32_t ulR28; - uint32_t ulR29; - uint32_t ulR30; - uint32_t ulR31; - uint32_t ulPC; - uint32_t ulESR; - uint32_t ulMSR; - uint32_t ulEAR; - uint32_t ulFSR; - uint32_t ulEDR; + UINTPTR ulR1_SP; + UINTPTR ulR2_small_data_area; + UINTPTR ulR3; + UINTPTR ulR4; + UINTPTR ulR5; + UINTPTR ulR6; + UINTPTR ulR7; + UINTPTR ulR8; + UINTPTR ulR9; + UINTPTR ulR10; + UINTPTR ulR11; + UINTPTR ulR12; + UINTPTR ulR13_read_write_small_data_area; + UINTPTR ulR14_return_address_from_interrupt; + UINTPTR ulR15_return_address_from_subroutine; + UINTPTR ulR16_return_address_from_trap; + UINTPTR ulR17_return_address_from_exceptions; /* The exception entry code will copy the BTR into R17 if the exception occurred in the delay slot of a branch instruction. */ + UINTPTR ulR18; + UINTPTR ulR19; + UINTPTR ulR20; + UINTPTR ulR21; + UINTPTR ulR22; + UINTPTR ulR23; + UINTPTR ulR24; + UINTPTR ulR25; + UINTPTR ulR26; + UINTPTR ulR27; + UINTPTR ulR28; + UINTPTR ulR29; + UINTPTR ulR30; + UINTPTR ulR31; + UINTPTR ulPC; + UINTPTR ulESR; + UINTPTR ulMSR; + UINTPTR ulEAR; + UINTPTR ulFSR; + UINTPTR ulEDR; /* A human readable description of the exception cause. The strings used * are the same as the #define constant names found in the @@ -384,4 +394,4 @@ void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump ); #endif /* *INDENT-ON* */ -#endif /* PORTMACRO_H */ +#endif /* PORTMACRO_H */ \ No newline at end of file diff --git a/portable/GCC/NiosII/port.c b/portable/GCC/NiosII/port.c index e427b4fcc..974c7d121 100644 --- a/portable/GCC/NiosII/port.c +++ b/portable/GCC/NiosII/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/NiosII/port_asm.S b/portable/GCC/NiosII/port_asm.S index 80117e590..1485ab3fc 100644 --- a/portable/GCC/NiosII/port_asm.S +++ b/portable/GCC/NiosII/port_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/NiosII/portmacro.h b/portable/GCC/NiosII/portmacro.h index b7b1d94a0..957f4db79 100644 --- a/portable/GCC/NiosII/portmacro.h +++ b/portable/GCC/NiosII/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC405_Xilinx/FPU_Macros.h b/portable/GCC/PPC405_Xilinx/FPU_Macros.h index 9d7f96ff9..8446c9ae1 100644 --- a/portable/GCC/PPC405_Xilinx/FPU_Macros.h +++ b/portable/GCC/PPC405_Xilinx/FPU_Macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC405_Xilinx/port.c b/portable/GCC/PPC405_Xilinx/port.c index a988dfc5e..c815cf265 100644 --- a/portable/GCC/PPC405_Xilinx/port.c +++ b/portable/GCC/PPC405_Xilinx/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC405_Xilinx/portasm.S b/portable/GCC/PPC405_Xilinx/portasm.S index 49866e83e..db3e3b916 100644 --- a/portable/GCC/PPC405_Xilinx/portasm.S +++ b/portable/GCC/PPC405_Xilinx/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC405_Xilinx/portmacro.h b/portable/GCC/PPC405_Xilinx/portmacro.h index fe0ca70cd..128d75c37 100644 --- a/portable/GCC/PPC405_Xilinx/portmacro.h +++ b/portable/GCC/PPC405_Xilinx/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC440_Xilinx/FPU_Macros.h b/portable/GCC/PPC440_Xilinx/FPU_Macros.h index 9d7f96ff9..8446c9ae1 100644 --- a/portable/GCC/PPC440_Xilinx/FPU_Macros.h +++ b/portable/GCC/PPC440_Xilinx/FPU_Macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC440_Xilinx/port.c b/portable/GCC/PPC440_Xilinx/port.c index d36e74300..a17c25918 100644 --- a/portable/GCC/PPC440_Xilinx/port.c +++ b/portable/GCC/PPC440_Xilinx/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC440_Xilinx/portasm.S b/portable/GCC/PPC440_Xilinx/portasm.S index 49866e83e..db3e3b916 100644 --- a/portable/GCC/PPC440_Xilinx/portasm.S +++ b/portable/GCC/PPC440_Xilinx/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/PPC440_Xilinx/portmacro.h b/portable/GCC/PPC440_Xilinx/portmacro.h index fe0ca70cd..128d75c37 100644 --- a/portable/GCC/PPC440_Xilinx/portmacro.h +++ b/portable/GCC/PPC440_Xilinx/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * 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 df7be85fc..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 @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -31,7 +31,7 @@ * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * - * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that + * + FreeRTOS\Source\portable\GCC\RISC-V\portASM.S contains the code that * is common to all currently supported RISC-V chips. There is only one * portASM.S file because the same file is built for all RISC-V target chips. * @@ -46,7 +46,7 @@ * compiler's!) include path. For example, if the chip in use includes a core * local interrupter (CLINT) and does not include any chip specific register * extensions then add the path below to the assembler's include path: - * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions + * FreeRTOS\Source\portable\GCC\RISC-V\chip_specific_extensions\RV32I_CLINT_no_extensions * */ @@ -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/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h index d4850841f..3be456cb4 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h index 930e50354..9f93824bd 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h index bac15e4d8..5b9ef4c06 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -31,7 +31,7 @@ * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * - * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that + * + FreeRTOS\Source\portable\GCC\RISC-V\portASM.S contains the code that * is common to all currently supported RISC-V chips. There is only one * portASM.S file because the same file is built for all RISC-V target chips. * @@ -46,7 +46,7 @@ * compiler's!) include path. For example, if the chip in use includes a core * local interrupter (CLINT) and does not include any chip specific register * extensions then add the path below to the assembler's include path: - * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions + * FreeRTOS\Source\portable\GCC\RISC-V\chip_specific_extensions\RV32I_CLINT_no_extensions * */ diff --git a/portable/GCC/RISC-V/chip_specific_extensions/readme.txt b/portable/GCC/RISC-V/chip_specific_extensions/readme.txt index b24c0b9fb..3e83157d7 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/readme.txt +++ b/portable/GCC/RISC-V/chip_specific_extensions/readme.txt @@ -3,7 +3,7 @@ * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * - * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that + * + FreeRTOS\Source\portable\GCC\RISC-V\portASM.S contains the code that * is common to all currently supported RISC-V chips. There is only one * portASM.S file because the same file is built for all RISC-V target chips. * @@ -18,6 +18,6 @@ * compiler's!) include path. For example, if the chip in use includes a core * local interrupter (CLINT) and does not include any chip specific register * extensions then add the path below to the assembler's include path: - * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions + * FreeRTOS\Source\portable\GCC\RISC-V\chip_specific_extensions\RV32I_CLINT_no_extensions * */ diff --git a/portable/GCC/RISC-V/port.c b/portable/GCC/RISC-V/port.c index e0648aa9c..8fe7a25d5 100644 --- a/portable/GCC/RISC-V/port.c +++ b/portable/GCC/RISC-V/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -27,8 +27,8 @@ */ /*----------------------------------------------------------- -* Implementation of functions defined in portable.h for the RISC-V port. -*----------------------------------------------------------*/ + * Implementation of functions defined in portable.h for the RISC-V port. + *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" @@ -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. */ -uint32_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 9dde71f6a..3d1d058cd 100644 --- a/portable/GCC/RISC-V/portASM.S +++ b/portable/GCC/RISC-V/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -32,7 +32,7 @@ * RISC-V ISA), and code which tailors the port to a specific RISC-V chip: * * + The code that is common to all RISC-V chips is implemented in - * FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S. There is only one + * FreeRTOS\Source\portable\GCC\RISC-V\portASM.S. There is only one * portASM.S file because the same file is used no matter which RISC-V chip is * in use. * @@ -138,7 +138,7 @@ definitions. */ * for the function is as per the other ports: * StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ); * - * As per the standard RISC-V ABI pxTopcOfStack is passed in in a0, pxCode in + * As per the standard RISC-V ABI pxTopOfStack is passed in in a0, pxCode in * a1, and pvParameters in a2. The new top of stack is passed out in a0. * * RISC-V maps registers to ABI names as follows (X1 to X31 integer registers @@ -158,11 +158,10 @@ definitions. */ * x18-27 s2-11 Saved registers Callee * x28-31 t3-6 Temporaries Caller * - * The RISC-V context is saved t FreeRTOS tasks in the following stack frame, + * The RISC-V context is saved to FreeRTOS tasks in the following stack frame, * 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 7eb871a14..95b84dd1a 100644 --- a/portable/GCC/RISC-V/portContext.h +++ b/portable/GCC/RISC-V/portContext.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -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/GCC/RISC-V/portmacro.h b/portable/GCC/RISC-V/portmacro.h index e40af6639..a516a2467 100644 --- a/portable/GCC/RISC-V/portmacro.h +++ b/portable/GCC/RISC-V/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -111,9 +111,6 @@ extern void vTaskSwitchContext( void ); /* Critical section management. */ #define portCRITICAL_NESTING_IN_TCB 0 -#define portSET_INTERRUPT_MASK_FROM_ISR() 0 -#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue - #define portDISABLE_INTERRUPTS() __asm volatile ( "csrc mstatus, 8" ) #define portENABLE_INTERRUPTS() __asm volatile ( "csrs mstatus, 8" ) diff --git a/portable/GCC/RISC-V/readme.txt b/portable/GCC/RISC-V/readme.txt index b24c0b9fb..3e83157d7 100644 --- a/portable/GCC/RISC-V/readme.txt +++ b/portable/GCC/RISC-V/readme.txt @@ -3,7 +3,7 @@ * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * - * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that + * + FreeRTOS\Source\portable\GCC\RISC-V\portASM.S contains the code that * is common to all currently supported RISC-V chips. There is only one * portASM.S file because the same file is built for all RISC-V target chips. * @@ -18,6 +18,6 @@ * compiler's!) include path. For example, if the chip in use includes a core * local interrupter (CLINT) and does not include any chip specific register * extensions then add the path below to the assembler's include path: - * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions + * FreeRTOS\Source\portable\GCC\RISC-V\chip_specific_extensions\RV32I_CLINT_no_extensions * */ diff --git a/portable/GCC/RL78/isr_support.h b/portable/GCC/RL78/isr_support.h index 5f8e568bc..788718089 100644 --- a/portable/GCC/RL78/isr_support.h +++ b/portable/GCC/RL78/isr_support.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RL78/port.c b/portable/GCC/RL78/port.c index 00ff398c8..7dad2b12b 100644 --- a/portable/GCC/RL78/port.c +++ b/portable/GCC/RL78/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RL78/portasm.S b/portable/GCC/RL78/portasm.S index 18ac665ed..2f24db972 100644 --- a/portable/GCC/RL78/portasm.S +++ b/portable/GCC/RL78/portasm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RL78/portmacro.h b/portable/GCC/RL78/portmacro.h index eac8b1086..730cf50a3 100644 --- a/portable/GCC/RL78/portmacro.h +++ b/portable/GCC/RL78/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -106,7 +106,18 @@ typedef unsigned short UBaseType_t; /* Task utilities. */ #define portYIELD() __asm volatile ( "BRK" ) -#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) do { if( xHigherPriorityTaskWoken ) vTaskSwitchContext( ); } while( 0 ) +#ifndef configREQUIRE_ASM_ISR_WRAPPER + #define configREQUIRE_ASM_ISR_WRAPPER 1 +#endif +#if( configREQUIRE_ASM_ISR_WRAPPER == 1 ) + /* You must implement an assembly ISR wrapper (see the below for details) if you need an ISR to cause a context switch. + * https://www.freertos.org/Documentation/02-Kernel/03-Supported-devices/04-Demos/Renesas/RTOS_RL78_IAR_Demos#writing-interrupt-service-routines */ + #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) do { if( xHigherPriorityTaskWoken != pdFALSE ) vTaskSwitchContext(); } while( 0 ) +#else + /* You must not implement an assembly ISR wrapper even if you need an ISR to cause a context switch. + * The portYIELD, which is similar to role of an assembly ISR wrapper, runs only when a context switch is required. */ + #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) do { if( xHigherPriorityTaskWoken != pdFALSE ) portYIELD(); } while( 0 ) +#endif #define portNOP() __asm volatile ( "NOP" ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RX100/port.c b/portable/GCC/RX100/port.c index e7f72bde6..854587d44 100644 --- a/portable/GCC/RX100/port.c +++ b/portable/GCC/RX100/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RX100/portmacro.h b/portable/GCC/RX100/portmacro.h index 01bc3621b..052ee0be3 100644 --- a/portable/GCC/RX100/portmacro.h +++ b/portable/GCC/RX100/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -111,7 +111,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile( "MVTIPL %0" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #else diff --git a/portable/GCC/RX200/port.c b/portable/GCC/RX200/port.c index 6261bc75c..e58c96d13 100644 --- a/portable/GCC/RX200/port.c +++ b/portable/GCC/RX200/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RX200/portmacro.h b/portable/GCC/RX200/portmacro.h index aee4e4de3..16e41bc61 100644 --- a/portable/GCC/RX200/portmacro.h +++ b/portable/GCC/RX200/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -113,7 +113,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile( "MVTIPL %0" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #else diff --git a/portable/GCC/RX600/port.c b/portable/GCC/RX600/port.c index 94747bdbe..9e6a7b443 100644 --- a/portable/GCC/RX600/port.c +++ b/portable/GCC/RX600/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RX600/portmacro.h b/portable/GCC/RX600/portmacro.h index d441eb784..187b2b5bd 100644 --- a/portable/GCC/RX600/portmacro.h +++ b/portable/GCC/RX600/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -113,7 +113,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile( "MVTIPL %0" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #else diff --git a/portable/GCC/RX600v2/port.c b/portable/GCC/RX600v2/port.c index 56212de9c..c31d2c65c 100644 --- a/portable/GCC/RX600v2/port.c +++ b/portable/GCC/RX600v2/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RX600v2/portmacro.h b/portable/GCC/RX600v2/portmacro.h index d441eb784..187b2b5bd 100644 --- a/portable/GCC/RX600v2/portmacro.h +++ b/portable/GCC/RX600v2/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -113,7 +113,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile( "MVTIPL %0" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #else diff --git a/portable/GCC/RX700v3_DPFPU/port.c b/portable/GCC/RX700v3_DPFPU/port.c index 7aa1e741c..8ed1bcfa4 100644 --- a/portable/GCC/RX700v3_DPFPU/port.c +++ b/portable/GCC/RX700v3_DPFPU/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/RX700v3_DPFPU/portmacro.h b/portable/GCC/RX700v3_DPFPU/portmacro.h index 4f9b8a087..bbfd24f90 100644 --- a/portable/GCC/RX700v3_DPFPU/portmacro.h +++ b/portable/GCC/RX700v3_DPFPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -137,7 +137,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile( "MVTIPL %0" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #else diff --git a/portable/GCC/STR75x/port.c b/portable/GCC/STR75x/port.c index 09fab1897..941b72b5f 100644 --- a/portable/GCC/STR75x/port.c +++ b/portable/GCC/STR75x/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/STR75x/portISR.c b/portable/GCC/STR75x/portISR.c index 569a6c7d3..110c22a80 100644 --- a/portable/GCC/STR75x/portISR.c +++ b/portable/GCC/STR75x/portISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/STR75x/portmacro.h b/portable/GCC/STR75x/portmacro.h index b52d3a513..81a30dcb3 100644 --- a/portable/GCC/STR75x/portmacro.h +++ b/portable/GCC/STR75x/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/TriCore_1782/port.c b/portable/GCC/TriCore_1782/port.c index f8f54922a..1579d8e72 100644 --- a/portable/GCC/TriCore_1782/port.c +++ b/portable/GCC/TriCore_1782/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/TriCore_1782/portmacro.h b/portable/GCC/TriCore_1782/portmacro.h index 8c1a9c0eb..c1e0b14d5 100644 --- a/portable/GCC/TriCore_1782/portmacro.h +++ b/portable/GCC/TriCore_1782/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/TriCore_1782/porttrap.c b/portable/GCC/TriCore_1782/porttrap.c index 732a406b6..f0600d754 100644 --- a/portable/GCC/TriCore_1782/porttrap.c +++ b/portable/GCC/TriCore_1782/porttrap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/78K0R/ISR_Support.h b/portable/IAR/78K0R/ISR_Support.h index 2fa110c70..b5a1f4d1d 100644 --- a/portable/IAR/78K0R/ISR_Support.h +++ b/portable/IAR/78K0R/ISR_Support.h @@ -1,6 +1,6 @@ ; /* * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * ; * * ; * SPDX-License-Identifier: MIT * ; * diff --git a/portable/IAR/78K0R/port.c b/portable/IAR/78K0R/port.c index 97d390300..3183b89ab 100644 --- a/portable/IAR/78K0R/port.c +++ b/portable/IAR/78K0R/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/78K0R/portasm.s26 b/portable/IAR/78K0R/portasm.s26 index 6b6b76137..1cddc0caf 100644 --- a/portable/IAR/78K0R/portasm.s26 +++ b/portable/IAR/78K0R/portasm.s26 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/78K0R/portmacro.h b/portable/IAR/78K0R/portmacro.h index 206b82c22..e0ac8fb02 100644 --- a/portable/IAR/78K0R/portmacro.h +++ b/portable/IAR/78K0R/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CA5_No_GIC/port.c b/portable/IAR/ARM_CA5_No_GIC/port.c index 3cb7c0db2..31afbb567 100644 --- a/portable/IAR/ARM_CA5_No_GIC/port.c +++ b/portable/IAR/ARM_CA5_No_GIC/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CA5_No_GIC/portASM.h b/portable/IAR/ARM_CA5_No_GIC/portASM.h index 85050e523..c3f9978d2 100644 --- a/portable/IAR/ARM_CA5_No_GIC/portASM.h +++ b/portable/IAR/ARM_CA5_No_GIC/portASM.h @@ -1,158 +1,109 @@ -; /* - * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * ; * - * ; * SPDX-License-Identifier: MIT - * ; * - * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of - * ; * this software and associated documentation files (the "Software"), to deal in - * ; * the Software without restriction, including without limitation the rights to - * ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * ; * the Software, and to permit persons to whom the Software is furnished to do so, - * ; * subject to the following conditions: - * ; * - * ; * The above copyright notice and this permission notice shall be included in all - * ; * copies or substantial portions of the Software. - * ; * - * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ; * - * ; * https://www.FreeRTOS.org - * ; * https://github.com/FreeRTOS - * ; * - * ; */ +;/* +; * FreeRTOS Kernel +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * +; * SPDX-License-Identifier: MIT +; * +; * Permission is hereby granted, free of charge, to any person obtaining a copy of +; * this software and associated documentation files (the "Software"), to deal in +; * the Software without restriction, including without limitation the rights to +; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +; * the Software, and to permit persons to whom the Software is furnished to do so, +; * subject to the following conditions: +; * +; * The above copyright notice and this permission notice shall be included in all +; * copies or substantial portions of the Software. +; * +; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +; * +; * https://www.FreeRTOS.org +; * https://github.com/FreeRTOS +; * +; */ -EXTERN vTaskSwitchContext -EXTERN ulCriticalNesting -EXTERN pxCurrentTCB -EXTERN ulPortTaskHasFPUContext -EXTERN ulAsmAPIPriorityMask + EXTERN vTaskSwitchContext + EXTERN ulCriticalNesting + EXTERN pxCurrentTCB + EXTERN ulPortTaskHasFPUContext + EXTERN ulAsmAPIPriorityMask portSAVE_CONTEXT macro -; -Save the LR and SPSR onto the system mode stack before switching to -; -system mode to save the remaining system mode registers -SRSDB sp !, # SYS_MODE - CPS # SYS_MODE - PUSH { - R0 - R12, R14 -} + ; Save the LR and SPSR onto the system mode stack before switching to + ; system mode to save the remaining system mode registers + SRSDB sp!, #SYS_MODE + CPS #SYS_MODE + PUSH {R0-R12, R14} -; -Push the critical nesting count -LDR R2, = ulCriticalNesting - LDR R1, [ R2 ] -PUSH { - R1 -} + ; Push the critical nesting count + LDR R2, =ulCriticalNesting + LDR R1, [R2] + PUSH {R1} -; -Does the task have a floating point context that needs saving ? If -; -ulPortTaskHasFPUContext is 0 then no. - LDR R2, = ulPortTaskHasFPUContext - LDR R3, [ R2 ] -CMP R3, # 0 - -; -Save the floating point context, - -if any -FMRXNE R1, FPSCR - VPUSHNE { - D0 - D15 -} + ; Does the task have a floating point context that needs saving? If + ; ulPortTaskHasFPUContext is 0 then no. + LDR R2, =ulPortTaskHasFPUContext + LDR R3, [R2] + CMP R3, #0 + ; Save the floating point context, if any + FMRXNE R1, FPSCR + VPUSHNE {D0-D15} #if configFPU_D32 == 1 -VPUSHNE { - D16 - D31 -} -#endif; configFPU_D32 -PUSHNE { - R1 -} + VPUSHNE {D16-D31} +#endif ; configFPU_D32 + PUSHNE {R1} -; -Save ulPortTaskHasFPUContext itself - PUSH { - R3 -} + ; Save ulPortTaskHasFPUContext itself + PUSH {R3} -; -Save the stack pointer in the TCB -LDR R0, = pxCurrentTCB - LDR R1, [ R0 ] -STR SP, [ R1 ] + ; Save the stack pointer in the TCB + LDR R0, =pxCurrentTCB + LDR R1, [R0] + STR SP, [R1] -endm + endm ; /**********************************************************************/ portRESTORE_CONTEXT macro -; -Set the SP to point to the stack of the task being restored. - LDR R0, = pxCurrentTCB - LDR R1, [ R0 ] -LDR SP, [ R1 ] + ; Set the SP to point to the stack of the task being restored. + LDR R0, =pxCurrentTCB + LDR R1, [R0] + LDR SP, [R1] -; -Is there a floating point context to restore ? If the restored -; -ulPortTaskHasFPUContext is zero then no. - LDR R0, = ulPortTaskHasFPUContext - POP { - R1 -} -STR R1, [ R0 ] -CMP R1, # 0 - -; -Restore the floating point context, - -if any - POPNE { - R0 -} + ; Is there a floating point context to restore? If the restored + ; ulPortTaskHasFPUContext is zero then no. + LDR R0, =ulPortTaskHasFPUContext + POP {R1} + STR R1, [R0] + CMP R1, #0 + ; Restore the floating point context, if any + POPNE {R0} #if configFPU_D32 == 1 -VPOPNE { - D16 - D31 -} -#endif; configFPU_D32 -VPOPNE { - D0 - D15 -} -VMSRNE FPSCR, R0 + VPOPNE {D16-D31} +#endif ; configFPU_D32 + VPOPNE {D0-D15} + VMSRNE FPSCR, R0 -; -Restore the critical section nesting depth -LDR R0, = ulCriticalNesting - POP { - R1 -} -STR R1, [ R0 ] + ; Restore the critical section nesting depth + LDR R0, =ulCriticalNesting + POP {R1} + STR R1, [R0] -; -Restore all system mode registers other than the SP( which is already - ; - being used ) -POP -{ - R0 - R12, R14 -} + ; Restore all system mode registers other than the SP (which is already + ; being used) + POP {R0-R12, R14} -Return to the task code, loading CPSR on the way.CPSR has the interrupt -; -enable bit set appropriately + ; Return to the task code, loading CPSR on the way. CPSR has the interrupt + ; enable bit set appropriately for the task about to execute. + RFEIA sp! -for the task about to execute. - RFEIA sp ! - -endm + endm diff --git a/portable/IAR/ARM_CA5_No_GIC/portASM.s b/portable/IAR/ARM_CA5_No_GIC/portASM.s index 8edcb6c55..dcfaa6043 100644 --- a/portable/IAR/ARM_CA5_No_GIC/portASM.s +++ b/portable/IAR/ARM_CA5_No_GIC/portASM.s @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/ARM_CA5_No_GIC/portmacro.h b/portable/IAR/ARM_CA5_No_GIC/portmacro.h index 82794345d..8d5caeb8a 100644 --- a/portable/IAR/ARM_CA5_No_GIC/portmacro.h +++ b/portable/IAR/ARM_CA5_No_GIC/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CA9/port.c b/portable/IAR/ARM_CA9/port.c index 3f87288ae..66852f9a7 100644 --- a/portable/IAR/ARM_CA9/port.c +++ b/portable/IAR/ARM_CA9/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -427,7 +427,7 @@ uint32_t ulPortSetInterruptMask( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); /* Priority grouping: The interrupt controller (GIC) allows the bits @@ -438,7 +438,7 @@ uint32_t ulPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/IAR/ARM_CA9/portASM.h b/portable/IAR/ARM_CA9/portASM.h index 8c21efed5..181530b67 100644 --- a/portable/IAR/ARM_CA9/portASM.h +++ b/portable/IAR/ARM_CA9/portASM.h @@ -1,160 +1,111 @@ -; /* - * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * ; * - * ; * SPDX-License-Identifier: MIT - * ; * - * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of - * ; * this software and associated documentation files (the "Software"), to deal in - * ; * the Software without restriction, including without limitation the rights to - * ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * ; * the Software, and to permit persons to whom the Software is furnished to do so, - * ; * subject to the following conditions: - * ; * - * ; * The above copyright notice and this permission notice shall be included in all - * ; * copies or substantial portions of the Software. - * ; * - * ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ; * - * ; * https://www.FreeRTOS.org - * ; * https://github.com/FreeRTOS - * ; * - * ; */ +;/* +; * FreeRTOS Kernel +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * +; * SPDX-License-Identifier: MIT +; * +; * Permission is hereby granted, free of charge, to any person obtaining a copy of +; * this software and associated documentation files (the "Software"), to deal in +; * the Software without restriction, including without limitation the rights to +; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +; * the Software, and to permit persons to whom the Software is furnished to do so, +; * subject to the following conditions: +; * +; * The above copyright notice and this permission notice shall be included in all +; * copies or substantial portions of the Software. +; * +; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +; * +; * https://www.FreeRTOS.org +; * https://github.com/FreeRTOS +; * +; */ -EXTERN vTaskSwitchContext -EXTERN ulCriticalNesting -EXTERN pxCurrentTCB -EXTERN ulPortTaskHasFPUContext -EXTERN ulAsmAPIPriorityMask + EXTERN vTaskSwitchContext + EXTERN ulCriticalNesting + EXTERN pxCurrentTCB + EXTERN ulPortTaskHasFPUContext + EXTERN ulAsmAPIPriorityMask portSAVE_CONTEXT macro -; -Save the LR and SPSR onto the system mode stack before switching to -; -system mode to save the remaining system mode registers -SRSDB sp !, # SYS_MODE - CPS # SYS_MODE - PUSH { - R0 - R12, R14 -} + ; Save the LR and SPSR onto the system mode stack before switching to + ; system mode to save the remaining system mode registers + SRSDB sp!, #SYS_MODE + CPS #SYS_MODE + PUSH {R0-R12, R14} -; -Push the critical nesting count -LDR R2, = ulCriticalNesting - LDR R1, [ R2 ] -PUSH { - R1 -} + ; Push the critical nesting count + LDR R2, =ulCriticalNesting + LDR R1, [R2] + PUSH {R1} -; -Does the task have a floating point context that needs saving ? If -; -ulPortTaskHasFPUContext is 0 then no. - LDR R2, = ulPortTaskHasFPUContext - LDR R3, [ R2 ] -CMP R3, # 0 + ; Does the task have a floating point context that needs saving? If + ; ulPortTaskHasFPUContext is 0 then no. + LDR R2, =ulPortTaskHasFPUContext + LDR R3, [R2] + CMP R3, #0 -; -Save the floating point context, + ; Save the floating point context, if any + FMRXNE R1, FPSCR + VPUSHNE {D0-D15} + VPUSHNE {D16-D31} + PUSHNE {R1} -if any -FMRXNE R1, FPSCR - VPUSHNE { - D0 - D15 -} + ; Save ulPortTaskHasFPUContext itself + PUSH {R3} -VPUSHNE { - D16 - D31 -} -PUSHNE { - R1 -} + ; Save the stack pointer in the TCB + LDR R0, =pxCurrentTCB + LDR R1, [R0] + STR SP, [R1] -; -Save ulPortTaskHasFPUContext itself - PUSH { - R3 -} - -; -Save the stack pointer in the TCB -LDR R0, = pxCurrentTCB - LDR R1, [ R0 ] -STR SP, [ R1 ] - -endm + endm ; /**********************************************************************/ portRESTORE_CONTEXT macro -; -Set the SP to point to the stack of the task being restored. - LDR R0, = pxCurrentTCB - LDR R1, [ R0 ] -LDR SP, [ R1 ] + ; Set the SP to point to the stack of the task being restored. + LDR R0, =pxCurrentTCB + LDR R1, [R0] + LDR SP, [R1] -; -Is there a floating point context to restore ? If the restored -; -ulPortTaskHasFPUContext is zero then no. - LDR R0, = ulPortTaskHasFPUContext - POP { - R1 -} -STR R1, [ R0 ] -CMP R1, # 0 + ; Is there a floating point context to restore? If the restored + ; ulPortTaskHasFPUContext is zero then no. + LDR R0, =ulPortTaskHasFPUContext + POP {R1} + STR R1, [R0] + CMP R1, #0 -; -Restore the floating point context, + ; Restore the floating point context, if any + POPNE {R0} + VPOPNE {D16-D31} + VPOPNE {D0-D15} + VMSRNE FPSCR, R0 -if any - POPNE { - R0 -} + ; Restore the critical section nesting depth + LDR R0, =ulCriticalNesting + POP {R1} + STR R1, [R0] -VPOPNE { - D16 - D31 -} -VPOPNE { - D0 - D15 -} -VMSRNE FPSCR, R0 + ; Ensure the priority mask is correct for the critical nesting depth + LDR R2, =portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS + CMP R1, #0 + MOVEQ R4, #255 + LDRNE R4, =( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) + STR R4, [r2] -; -Restore the critical section nesting depth -LDR R0, = ulCriticalNesting - POP { - R1 -} -STR R1, [ R0 ] + ; Restore all system mode registers other than the SP (which is already + ; being used) + POP {R0-R12, R14} -; -Ensure the priority mask is correct + ; Return to the task code, loading CPSR on the way. + RFEIA sp! -for the critical nesting depth -LDR R2, = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS - CMP R1, # 0 -MOVEQ R4, # 255 -LDRNE R4, = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) - STR R4, [ r2 ] - -; -Restore all system mode registers other than the SP( which is already - ; - being used ) -POP -{ - R0 - R12, R14 -} - -Return to the task code, loading CPSR on the way. - RFEIA sp ! - -endm + endm diff --git a/portable/IAR/ARM_CA9/portASM.s b/portable/IAR/ARM_CA9/portASM.s index 56ec384c0..d7d07995f 100644 --- a/portable/IAR/ARM_CA9/portASM.s +++ b/portable/IAR/ARM_CA9/portASM.s @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/ARM_CA9/portmacro.h b/portable/IAR/ARM_CA9/portmacro.h index 4782a5a66..f1cb124a2 100644 --- a/portable/IAR/ARM_CA9/portmacro.h +++ b/portable/IAR/ARM_CA9/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -151,7 +151,7 @@ #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ - #ifdef configASSERT + #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ diff --git a/portable/IAR/ARM_CM0/port.c b/portable/IAR/ARM_CM0/port.c index 1b9caa13a..6f5ec0ad5 100644 --- a/portable/IAR/ARM_CM0/port.c +++ b/portable/IAR/ARM_CM0/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -180,7 +180,7 @@ static void prvTaskExitError( void ) BaseType_t xPortStartScheduler( void ) { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the function xPortPendSVHandler for PendSV * interrupt. * 2. Indirect Routing - Install separate handler for PendSV interrupt and @@ -205,7 +205,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handler. For help installing the FreeRTOS handler, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if diff --git a/portable/IAR/ARM_CM0/portasm.s b/portable/IAR/ARM_CM0/portasm.s index ede492135..6c19a1749 100644 --- a/portable/IAR/ARM_CM0/portasm.s +++ b/portable/IAR/ARM_CM0/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM0/portmacro.h b/portable/IAR/ARM_CM0/portmacro.h index 88cba2016..a097db9df 100644 --- a/portable/IAR/ARM_CM0/portmacro.h +++ b/portable/IAR/ARM_CM0/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S index 419df5b1e..9289bcbc2 100644 --- a/portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -48,12 +48,11 @@ MPU_xTaskDelayUntil: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0, r1} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -63,12 +62,11 @@ MPU_xTaskAbortDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0, r1} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -78,12 +76,11 @@ MPU_vTaskDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0, r1} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -93,12 +90,11 @@ MPU_uxTaskPriorityGet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0, r1} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -108,12 +104,11 @@ MPU_eTaskGetState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0, r1} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -123,12 +118,11 @@ MPU_vTaskGetInfo: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0, r1} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -138,12 +132,11 @@ MPU_xTaskGetIdleTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -153,12 +146,11 @@ MPU_vTaskSuspend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0, r1} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -168,12 +160,11 @@ MPU_vTaskResume: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0, r1} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -183,12 +174,11 @@ MPU_xTaskGetTickCount: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0, r1} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -198,12 +188,11 @@ MPU_uxTaskGetNumberOfTasks: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0, r1} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -213,12 +202,11 @@ MPU_ulTaskGetRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -228,12 +216,11 @@ MPU_ulTaskGetRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +230,11 @@ MPU_ulTaskGetIdleRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -258,12 +244,11 @@ MPU_ulTaskGetIdleRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -273,12 +258,11 @@ MPU_vTaskSetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -288,12 +272,11 @@ MPU_xTaskGetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -303,12 +286,11 @@ MPU_vTaskSetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -318,12 +300,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -333,12 +314,11 @@ MPU_uxTaskGetSystemState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0, r1} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -348,12 +328,11 @@ MPU_uxTaskGetStackHighWaterMark: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -363,12 +342,11 @@ MPU_uxTaskGetStackHighWaterMark2: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -378,12 +356,11 @@ MPU_xTaskGetCurrentTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -393,12 +370,11 @@ MPU_xTaskGetSchedulerState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0, r1} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -408,12 +384,11 @@ MPU_vTaskSetTimeOutState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0, r1} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -423,12 +398,11 @@ MPU_xTaskCheckForTimeOut: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0, r1} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -438,12 +412,11 @@ MPU_xTaskGenericNotifyEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -453,12 +426,11 @@ MPU_xTaskGenericNotifyWaitEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -468,12 +440,11 @@ MPU_ulTaskGenericNotifyTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -483,12 +454,11 @@ MPU_xTaskGenericNotifyStateClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -498,12 +468,11 @@ MPU_ulTaskGenericNotifyValueClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -513,12 +482,11 @@ MPU_xQueueGenericSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0, r1} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -528,12 +496,11 @@ MPU_uxQueueMessagesWaiting: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0, r1} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -543,12 +510,11 @@ MPU_uxQueueSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0, r1} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -558,12 +524,11 @@ MPU_xQueueReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0, r1} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -573,12 +538,11 @@ MPU_xQueuePeek: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0, r1} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -588,12 +552,11 @@ MPU_xQueueSemaphoreTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0, r1} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -603,12 +566,11 @@ MPU_xQueueGetMutexHolder: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0, r1} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -618,12 +580,11 @@ MPU_xQueueTakeMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -633,12 +594,11 @@ MPU_xQueueGiveMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -648,12 +608,11 @@ MPU_xQueueSelectFromSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0, r1} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -663,12 +622,11 @@ MPU_xQueueAddToSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0, r1} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -678,12 +636,11 @@ MPU_vQueueAddToRegistry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0, r1} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -693,12 +650,11 @@ MPU_vQueueUnregisterQueue: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0, r1} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -708,12 +664,11 @@ MPU_pcQueueGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0, r1} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -723,12 +678,11 @@ MPU_pvTimerGetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0, r1} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -738,12 +692,11 @@ MPU_vTimerSetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0, r1} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -753,12 +706,11 @@ MPU_xTimerIsTimerActive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0, r1} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -768,12 +720,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0, r1} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -783,12 +734,11 @@ MPU_xTimerGenericCommandFromTaskEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0, r1} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -798,12 +748,11 @@ MPU_pcTimerGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0, r1} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -813,12 +762,11 @@ MPU_vTimerSetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0, r1} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -828,12 +776,11 @@ MPU_xTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -843,12 +790,11 @@ MPU_uxTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -858,12 +804,11 @@ MPU_xTimerGetPeriod: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0, r1} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -873,12 +818,11 @@ MPU_xTimerGetExpiryTime: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0, r1} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -888,12 +832,11 @@ MPU_xEventGroupWaitBitsEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0, r1} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -903,12 +846,11 @@ MPU_xEventGroupClearBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0, r1} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -918,12 +860,11 @@ MPU_xEventGroupSetBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0, r1} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -933,12 +874,11 @@ MPU_xEventGroupSync: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0, r1} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -948,12 +888,11 @@ MPU_uxEventGroupGetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0, r1} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -963,12 +902,11 @@ MPU_vEventGroupSetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0, r1} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -978,12 +916,11 @@ MPU_xStreamBufferSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0, r1} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -993,12 +930,11 @@ MPU_xStreamBufferReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0, r1} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -1008,12 +944,11 @@ MPU_xStreamBufferIsFull: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0, r1} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -1023,12 +958,11 @@ MPU_xStreamBufferIsEmpty: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0, r1} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -1038,12 +972,11 @@ MPU_xStreamBufferSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -1053,12 +986,11 @@ MPU_xStreamBufferBytesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -1068,12 +1000,11 @@ MPU_xStreamBufferSetTriggerLevel: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0, r1} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1083,12 +1014,11 @@ MPU_xStreamBufferNextMessageLengthBytes: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0, r1} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portasm.h b/portable/IAR/ARM_CM23/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM23/non_secure/portasm.h +++ b/portable/IAR/ARM_CM23/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM23/non_secure/portasm.s b/portable/IAR/ARM_CM23/non_secure/portasm.s index 06c761090..6817abd7a 100644 --- a/portable/IAR/ARM_CM23/non_secure/portasm.s +++ b/portable/IAR/ARM_CM23/non_secure/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23/non_secure/portmacro.h b/portable/IAR/ARM_CM23/non_secure/portmacro.h index e426f5b9a..9d6c3368e 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.c +++ b/portable/IAR/ARM_CM23/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM23/secure/secure_context.h b/portable/IAR/ARM_CM23/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.h +++ b/portable/IAR/ARM_CM23/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s index f7c5d19d2..f70e89115 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s +++ b/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23/secure/secure_heap.c b/portable/IAR/ARM_CM23/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/IAR/ARM_CM23/secure/secure_heap.c +++ b/portable/IAR/ARM_CM23/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/IAR/ARM_CM23/secure/secure_heap.h b/portable/IAR/ARM_CM23/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/IAR/ARM_CM23/secure/secure_heap.h +++ b/portable/IAR/ARM_CM23/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23/secure/secure_init.c b/portable/IAR/ARM_CM23/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/IAR/ARM_CM23/secure/secure_init.c +++ b/portable/IAR/ARM_CM23/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23/secure/secure_init.h b/portable/IAR/ARM_CM23/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/IAR/ARM_CM23/secure/secure_init.h +++ b/portable/IAR/ARM_CM23/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23/secure/secure_port_macros.h b/portable/IAR/ARM_CM23/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/IAR/ARM_CM23/secure/secure_port_macros.h +++ b/portable/IAR/ARM_CM23/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S index 419df5b1e..9289bcbc2 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -48,12 +48,11 @@ MPU_xTaskDelayUntil: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0, r1} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -63,12 +62,11 @@ MPU_xTaskAbortDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0, r1} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -78,12 +76,11 @@ MPU_vTaskDelay: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0, r1} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -93,12 +90,11 @@ MPU_uxTaskPriorityGet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0, r1} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -108,12 +104,11 @@ MPU_eTaskGetState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0, r1} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -123,12 +118,11 @@ MPU_vTaskGetInfo: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0, r1} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -138,12 +132,11 @@ MPU_xTaskGetIdleTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -153,12 +146,11 @@ MPU_vTaskSuspend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0, r1} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -168,12 +160,11 @@ MPU_vTaskResume: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0, r1} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -183,12 +174,11 @@ MPU_xTaskGetTickCount: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0, r1} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -198,12 +188,11 @@ MPU_uxTaskGetNumberOfTasks: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0, r1} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -213,12 +202,11 @@ MPU_ulTaskGetRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -228,12 +216,11 @@ MPU_ulTaskGetRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +230,11 @@ MPU_ulTaskGetIdleRunTimePercent: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -258,12 +244,11 @@ MPU_ulTaskGetIdleRunTimeCounter: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0, r1} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -273,12 +258,11 @@ MPU_vTaskSetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -288,12 +272,11 @@ MPU_xTaskGetApplicationTaskTag: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0, r1} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -303,12 +286,11 @@ MPU_vTaskSetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -318,12 +300,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0, r1} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -333,12 +314,11 @@ MPU_uxTaskGetSystemState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0, r1} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -348,12 +328,11 @@ MPU_uxTaskGetStackHighWaterMark: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -363,12 +342,11 @@ MPU_uxTaskGetStackHighWaterMark2: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0, r1} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -378,12 +356,11 @@ MPU_xTaskGetCurrentTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0, r1} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -393,12 +370,11 @@ MPU_xTaskGetSchedulerState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0, r1} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -408,12 +384,11 @@ MPU_vTaskSetTimeOutState: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0, r1} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -423,12 +398,11 @@ MPU_xTaskCheckForTimeOut: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0, r1} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -438,12 +412,11 @@ MPU_xTaskGenericNotifyEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -453,12 +426,11 @@ MPU_xTaskGenericNotifyWaitEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -468,12 +440,11 @@ MPU_ulTaskGenericNotifyTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -483,12 +454,11 @@ MPU_xTaskGenericNotifyStateClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0, r1} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -498,12 +468,11 @@ MPU_ulTaskGenericNotifyValueClear: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0, r1} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -513,12 +482,11 @@ MPU_xQueueGenericSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0, r1} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -528,12 +496,11 @@ MPU_uxQueueMessagesWaiting: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0, r1} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -543,12 +510,11 @@ MPU_uxQueueSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0, r1} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -558,12 +524,11 @@ MPU_xQueueReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0, r1} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -573,12 +538,11 @@ MPU_xQueuePeek: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0, r1} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -588,12 +552,11 @@ MPU_xQueueSemaphoreTake: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0, r1} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -603,12 +566,11 @@ MPU_xQueueGetMutexHolder: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0, r1} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -618,12 +580,11 @@ MPU_xQueueTakeMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -633,12 +594,11 @@ MPU_xQueueGiveMutexRecursive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0, r1} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -648,12 +608,11 @@ MPU_xQueueSelectFromSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0, r1} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -663,12 +622,11 @@ MPU_xQueueAddToSet: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0, r1} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -678,12 +636,11 @@ MPU_vQueueAddToRegistry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0, r1} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -693,12 +650,11 @@ MPU_vQueueUnregisterQueue: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0, r1} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -708,12 +664,11 @@ MPU_pcQueueGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0, r1} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -723,12 +678,11 @@ MPU_pvTimerGetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0, r1} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -738,12 +692,11 @@ MPU_vTimerSetTimerID: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0, r1} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -753,12 +706,11 @@ MPU_xTimerIsTimerActive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0, r1} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -768,12 +720,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0, r1} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -783,12 +734,11 @@ MPU_xTimerGenericCommandFromTaskEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0, r1} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -798,12 +748,11 @@ MPU_pcTimerGetName: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0, r1} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -813,12 +762,11 @@ MPU_vTimerSetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0, r1} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -828,12 +776,11 @@ MPU_xTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -843,12 +790,11 @@ MPU_uxTimerGetReloadMode: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0, r1} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -858,12 +804,11 @@ MPU_xTimerGetPeriod: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0, r1} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -873,12 +818,11 @@ MPU_xTimerGetExpiryTime: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0, r1} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -888,12 +832,11 @@ MPU_xEventGroupWaitBitsEntry: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0, r1} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -903,12 +846,11 @@ MPU_xEventGroupClearBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0, r1} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -918,12 +860,11 @@ MPU_xEventGroupSetBits: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0, r1} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -933,12 +874,11 @@ MPU_xEventGroupSync: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0, r1} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -948,12 +888,11 @@ MPU_uxEventGroupGetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0, r1} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -963,12 +902,11 @@ MPU_vEventGroupSetNumber: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0, r1} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -978,12 +916,11 @@ MPU_xStreamBufferSend: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0, r1} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -993,12 +930,11 @@ MPU_xStreamBufferReceive: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0, r1} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -1008,12 +944,11 @@ MPU_xStreamBufferIsFull: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0, r1} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -1023,12 +958,11 @@ MPU_xStreamBufferIsEmpty: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0, r1} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -1038,12 +972,11 @@ MPU_xStreamBufferSpacesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -1053,12 +986,11 @@ MPU_xStreamBufferBytesAvailable: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0, r1} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -1068,12 +1000,11 @@ MPU_xStreamBufferSetTriggerLevel: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0, r1} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1083,12 +1014,11 @@ MPU_xStreamBufferNextMessageLengthBytes: mrs r0, control movs r1, #1 tst r0, r1 + pop {r0, r1} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0, r1} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0, r1} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s index d4487dfac..bfe9eee4b 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h index e426f5b9a..9d6c3368e 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -60,6 +61,12 @@ #if ( configTOTAL_MPU_REGIONS == 16 ) #error 16 MPU regions are not yet supported for this port. #endif + +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. +#endif /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c index 460826872..ef590cf95 100644 --- a/portable/IAR/ARM_CM3/port.c +++ b/portable/IAR/ARM_CM3/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -223,7 +223,7 @@ static void prvTaskExitError( void ) BaseType_t xPortStartScheduler( void ) { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -246,7 +246,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -709,7 +709,7 @@ __weak void vPortSetupTimerInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/IAR/ARM_CM3/portasm.s b/portable/IAR/ARM_CM3/portasm.s index 0dbb43b00..7b2afde98 100644 --- a/portable/IAR/ARM_CM3/portasm.s +++ b/portable/IAR/ARM_CM3/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM3/portmacro.h b/portable/IAR/ARM_CM3/portmacro.h index c90a952e2..f49c618c4 100644 --- a/portable/IAR/ARM_CM3/portmacro.h +++ b/portable/IAR/ARM_CM3/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -173,7 +173,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.h b/portable/IAR/ARM_CM33/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.h +++ b/portable/IAR/ARM_CM33/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index d8f1b1d9a..8d5988819 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -150,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -175,12 +185,22 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +233,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -268,11 +288,20 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -326,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -371,76 +408,86 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - mov lr, r4 /* LR = r4. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM33/non_secure/portmacro.h b/portable/IAR/ARM_CM33/non_secure/portmacro.h index a707fc658..53b668b5b 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,18 +50,21 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /* ARMv8-M common port configurations. */ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. +#endif +/*-----------------------------------------------------------*/ + /** * @brief Critical section management. */ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.c +++ b/portable/IAR/ARM_CM33/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM33/secure/secure_context.h b/portable/IAR/ARM_CM33/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.h +++ b/portable/IAR/ARM_CM33/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s index 400bd0107..27a8f3933 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s +++ b/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM33/secure/secure_heap.c b/portable/IAR/ARM_CM33/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/IAR/ARM_CM33/secure/secure_heap.c +++ b/portable/IAR/ARM_CM33/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/IAR/ARM_CM33/secure/secure_heap.h b/portable/IAR/ARM_CM33/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/IAR/ARM_CM33/secure/secure_heap.h +++ b/portable/IAR/ARM_CM33/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM33/secure/secure_init.c b/portable/IAR/ARM_CM33/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/IAR/ARM_CM33/secure/secure_init.c +++ b/portable/IAR/ARM_CM33/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM33/secure/secure_init.h b/portable/IAR/ARM_CM33/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/IAR/ARM_CM33/secure/secure_init.h +++ b/portable/IAR/ARM_CM33/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM33/secure/secure_port_macros.h b/portable/IAR/ARM_CM33/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/IAR/ARM_CM33/secure/secure_port_macros.h +++ b/portable/IAR/ARM_CM33/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s index 7cf467d22..ba6e8e915 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -140,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -163,10 +173,20 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +219,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -230,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -239,11 +258,20 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -297,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -332,12 +368,21 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ +#if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -348,6 +393,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h index 64d39e3b9..53b668b5b 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -57,8 +58,10 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.h b/portable/IAR/ARM_CM35P/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.h +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s index d8f1b1d9a..8d5988819 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -150,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -175,12 +185,22 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +233,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -268,11 +288,20 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -326,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -371,76 +408,86 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - mov lr, r4 /* LR = r4. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacro.h b/portable/IAR/ARM_CM35P/non_secure/portmacro.h index 82bfaeb79..6e543efb5 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -57,8 +58,10 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.c b/portable/IAR/ARM_CM35P/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_context.c +++ b/portable/IAR/ARM_CM35P/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.h b/portable/IAR/ARM_CM35P/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_context.h +++ b/portable/IAR/ARM_CM35P/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s index 400bd0107..27a8f3933 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s +++ b/portable/IAR/ARM_CM35P/secure/secure_context_port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM35P/secure/secure_heap.c b/portable/IAR/ARM_CM35P/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_heap.c +++ b/portable/IAR/ARM_CM35P/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/IAR/ARM_CM35P/secure/secure_heap.h b/portable/IAR/ARM_CM35P/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_heap.h +++ b/portable/IAR/ARM_CM35P/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM35P/secure/secure_init.c b/portable/IAR/ARM_CM35P/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_init.c +++ b/portable/IAR/ARM_CM35P/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM35P/secure/secure_init.h b/portable/IAR/ARM_CM35P/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_init.h +++ b/portable/IAR/ARM_CM35P/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM35P/secure/secure_port_macros.h b/portable/IAR/ARM_CM35P/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_port_macros.h +++ b/portable/IAR/ARM_CM35P/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s index 7cf467d22..ba6e8e915 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -140,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -163,10 +173,20 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +219,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -230,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -239,11 +258,20 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -297,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -332,12 +368,21 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ +#if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -348,6 +393,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h index 82bfaeb79..6e543efb5 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -50,6 +50,7 @@ */ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -57,8 +58,10 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#elif ( configENABLE_MVE != 0 ) + #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c index 763ff2a5c..b96329a05 100644 --- a/portable/IAR/ARM_CM4F/port.c +++ b/portable/IAR/ARM_CM4F/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -261,7 +261,7 @@ BaseType_t xPortStartScheduler( void ) configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -284,7 +284,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -753,7 +753,7 @@ __weak void vPortSetupTimerInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/IAR/ARM_CM4F/portasm.s b/portable/IAR/ARM_CM4F/portasm.s index f4caf80bf..a2e8c3009 100644 --- a/portable/IAR/ARM_CM4F/portasm.s +++ b/portable/IAR/ARM_CM4F/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM4F/portmacro.h b/portable/IAR/ARM_CM4F/portmacro.h index 20467efcb..f3d8ace9d 100644 --- a/portable/IAR/ARM_CM4F/portmacro.h +++ b/portable/IAR/ARM_CM4F/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -172,7 +172,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S index d21dbaa7f..f01c01d42 100644 --- a/portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -51,12 +51,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -65,12 +64,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -79,12 +77,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -93,12 +90,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -107,12 +103,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -121,12 +116,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -135,12 +129,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -149,12 +142,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -163,12 +155,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -177,12 +168,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -191,12 +181,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -205,12 +194,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -219,12 +207,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -233,12 +220,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -247,12 +233,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -261,12 +246,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -275,12 +259,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -289,12 +272,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -303,12 +285,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -317,12 +298,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -331,12 +311,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -345,12 +324,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -359,12 +337,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -373,12 +350,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -387,12 +363,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -401,12 +376,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -415,12 +389,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -429,12 +402,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -443,12 +415,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -457,12 +428,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -471,12 +441,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -485,12 +454,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -499,12 +467,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -513,12 +480,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -527,12 +493,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -541,12 +506,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -555,12 +519,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -569,12 +532,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -583,12 +545,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -597,12 +558,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -611,12 +571,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -625,12 +584,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -639,12 +597,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -653,12 +610,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -667,12 +623,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -681,12 +636,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -695,12 +649,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -709,12 +662,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -723,12 +675,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -737,12 +688,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -751,12 +701,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -765,12 +714,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -779,12 +727,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -793,12 +740,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -807,12 +753,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -821,12 +766,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -835,12 +779,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -849,12 +792,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -863,12 +805,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -877,12 +818,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -891,12 +831,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -905,12 +844,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -919,12 +857,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -933,12 +870,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -947,12 +883,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -961,12 +896,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -975,12 +909,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -989,12 +922,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -1003,12 +935,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1017,12 +948,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index c3bab2671..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 (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -300,14 +302,14 @@ extern void xPortPendSVHandler( void ) PRIVILEGED_FUNCTION; * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; -#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) /* * This variable is set to pdTRUE when the scheduler is started. */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; -#endif +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure @@ -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 ]; } @@ -725,7 +735,7 @@ BaseType_t xPortStartScheduler( void ) #endif /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -748,7 +758,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -858,11 +868,11 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; - #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); @@ -1127,7 +1137,7 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { extern uint32_t __SRAM_segment_start__[]; extern uint32_t __SRAM_segment_end__[]; @@ -1172,7 +1182,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = @@ -1183,13 +1193,13 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | - ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( prvGetMPURegionSizeSetting( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + - ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1UL ); xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); } @@ -1244,45 +1254,57 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ -BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, - uint32_t ulBufferLength, - uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) -{ - uint32_t i, ulBufferStartAddress, ulBufferEndAddress; - BaseType_t xAccessGranted = pdFALSE; - const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { - xAccessGranted = pdTRUE; - } - else - { - if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( xSchedulerRunning == pdFALSE ) { - ulBufferStartAddress = ( uint32_t ) pvBuffer; - ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); - - for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) { - if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) { - xAccessGranted = pdTRUE; - break; + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } } } } + + return xAccessGranted; } - return xAccessGranted; -} +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ @@ -1324,7 +1346,7 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/IAR/ARM_CM4F_MPU/portasm.s b/portable/IAR/ARM_CM4F_MPU/portasm.s index 7866d9ee9..9ce0e14d8 100644 --- a/portable/IAR/ARM_CM4F_MPU/portasm.s +++ b/portable/IAR/ARM_CM4F_MPU/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM4F_MPU/portmacro.h b/portable/IAR/ARM_CM4F_MPU/portmacro.h index 5b994cca9..6b7600c15 100644 --- a/portable/IAR/ARM_CM4F_MPU/portmacro.h +++ b/portable/IAR/ARM_CM4F_MPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -100,7 +100,7 @@ typedef unsigned long UBaseType_t; #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -221,7 +221,16 @@ typedef struct MPU_REGION_SETTINGS #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -#define MAX_CONTEXT_SIZE ( 52 ) +/* + * +---------+---------------+-----------------+-----------------+-----+ + * | s16-s31 | s0-s15, FPSCR | CONTROL, r4-r11 | PSP, r0-r3, r12 | | + * | | | EXC_RETURN | LR, PC, xPSR | | + * +---------+---------------+-----------------+-----------------+-----+ + * + * <--------><---------------><----------------><----------------><----> + * 16 17 10 9 1 + */ +#define MAX_CONTEXT_SIZE ( 53 ) /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) @@ -345,7 +354,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.h b/portable/IAR/ARM_CM55/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.h +++ b/portable/IAR/ARM_CM55/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.s b/portable/IAR/ARM_CM55/non_secure/portasm.s index d8f1b1d9a..8d5988819 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -150,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -175,12 +185,22 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +233,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -268,11 +288,20 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -326,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -371,76 +408,86 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - mov lr, r4 /* LR = r4. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM55/non_secure/portmacro.h b/portable/IAR/ARM_CM55/non_secure/portmacro.h index 1338d25be..597af66fa 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -62,11 +63,6 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /** * @brief Critical section management. */ diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM55/secure/secure_context.c b/portable/IAR/ARM_CM55/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/IAR/ARM_CM55/secure/secure_context.c +++ b/portable/IAR/ARM_CM55/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM55/secure/secure_context.h b/portable/IAR/ARM_CM55/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/IAR/ARM_CM55/secure/secure_context.h +++ b/portable/IAR/ARM_CM55/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM55/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM55/secure/secure_context_port_asm.s index 400bd0107..27a8f3933 100644 --- a/portable/IAR/ARM_CM55/secure/secure_context_port_asm.s +++ b/portable/IAR/ARM_CM55/secure/secure_context_port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM55/secure/secure_heap.c b/portable/IAR/ARM_CM55/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/IAR/ARM_CM55/secure/secure_heap.c +++ b/portable/IAR/ARM_CM55/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/IAR/ARM_CM55/secure/secure_heap.h b/portable/IAR/ARM_CM55/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/IAR/ARM_CM55/secure/secure_heap.h +++ b/portable/IAR/ARM_CM55/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM55/secure/secure_init.c b/portable/IAR/ARM_CM55/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/IAR/ARM_CM55/secure/secure_init.c +++ b/portable/IAR/ARM_CM55/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM55/secure/secure_init.h b/portable/IAR/ARM_CM55/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/IAR/ARM_CM55/secure/secure_init.h +++ b/portable/IAR/ARM_CM55/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM55/secure/secure_port_macros.h b/portable/IAR/ARM_CM55/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/IAR/ARM_CM55/secure/secure_port_macros.h +++ b/portable/IAR/ARM_CM55/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s index 7cf467d22..ba6e8e915 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -140,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -163,10 +173,20 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +219,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -230,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -239,11 +258,20 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -297,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -332,12 +368,21 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ +#if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -348,6 +393,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h index 1338d25be..597af66fa 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -62,11 +63,6 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /** * @brief Critical section management. */ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c index 2790028f4..723389633 100644 --- a/portable/IAR/ARM_CM7/r0p1/port.c +++ b/portable/IAR/ARM_CM7/r0p1/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -249,7 +249,7 @@ static void prvTaskExitError( void ) BaseType_t xPortStartScheduler( void ) { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -272,7 +272,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -741,7 +741,7 @@ __weak void vPortSetupTimerInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/IAR/ARM_CM7/r0p1/portasm.s b/portable/IAR/ARM_CM7/r0p1/portasm.s index 483178d96..56d4b3e04 100644 --- a/portable/IAR/ARM_CM7/r0p1/portasm.s +++ b/portable/IAR/ARM_CM7/r0p1/portasm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM7/r0p1/portmacro.h b/portable/IAR/ARM_CM7/r0p1/portmacro.h index a6c377b6b..7c66ed3f9 100644 --- a/portable/IAR/ARM_CM7/r0p1/portmacro.h +++ b/portable/IAR/ARM_CM7/r0p1/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -175,7 +175,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.h b/portable/IAR/ARM_CM85/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.h +++ b/portable/IAR/ARM_CM85/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.s b/portable/IAR/ARM_CM85/non_secure/portasm.s index d8f1b1d9a..8d5988819 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -150,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -175,12 +185,22 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +233,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -268,11 +288,20 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -326,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -371,76 +408,86 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - mov lr, r4 /* LR = r4. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM85/non_secure/portmacro.h b/portable/IAR/ARM_CM85/non_secure/portmacro.h index cffcb20d9..ff5c9895d 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -62,11 +63,6 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /** * @brief Critical section management. */ diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CM85/secure/secure_context.c b/portable/IAR/ARM_CM85/secure/secure_context.c index 7d2171996..3aa335e63 100644 --- a/portable/IAR/ARM_CM85/secure/secure_context.c +++ b/portable/IAR/ARM_CM85/secure/secure_context.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM85/secure/secure_context.h b/portable/IAR/ARM_CM85/secure/secure_context.h index 0bf776198..e36a8e430 100644 --- a/portable/IAR/ARM_CM85/secure/secure_context.h +++ b/portable/IAR/ARM_CM85/secure/secure_context.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM85/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM85/secure/secure_context_port_asm.s index 400bd0107..27a8f3933 100644 --- a/portable/IAR/ARM_CM85/secure/secure_context_port_asm.s +++ b/portable/IAR/ARM_CM85/secure/secure_context_port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM85/secure/secure_heap.c b/portable/IAR/ARM_CM85/secure/secure_heap.c index 1ec3bdbdb..896b53e2d 100644 --- a/portable/IAR/ARM_CM85/secure/secure_heap.c +++ b/portable/IAR/ARM_CM85/secure/secure_heap.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,9 @@ /* Standard includes. */ #include +/* Configuration includes. */ +#include "FreeRTOSConfig.h" + /* Secure context heap includes. */ #include "secure_heap.h" @@ -234,7 +237,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -256,6 +259,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* If this is the first call to malloc then the heap will require * initialisation to setup the list of free blocks. */ @@ -374,6 +378,8 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned by * the application and has no "next" block. */ secureheapALLOCATE_BLOCK( pxBlock ); @@ -394,7 +400,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; #if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) { diff --git a/portable/IAR/ARM_CM85/secure/secure_heap.h b/portable/IAR/ARM_CM85/secure/secure_heap.h index c13590f86..0e84a9d9d 100644 --- a/portable/IAR/ARM_CM85/secure/secure_heap.h +++ b/portable/IAR/ARM_CM85/secure/secure_heap.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM85/secure/secure_init.c b/portable/IAR/ARM_CM85/secure/secure_init.c index b89c5f644..c50d37668 100644 --- a/portable/IAR/ARM_CM85/secure/secure_init.c +++ b/portable/IAR/ARM_CM85/secure/secure_init.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM85/secure/secure_init.h b/portable/IAR/ARM_CM85/secure/secure_init.h index 21daeda6b..ebe04900f 100644 --- a/portable/IAR/ARM_CM85/secure/secure_init.h +++ b/portable/IAR/ARM_CM85/secure/secure_init.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM85/secure/secure_port_macros.h b/portable/IAR/ARM_CM85/secure/secure_port_macros.h index 304913b8d..a70da2c65 100644 --- a/portable/IAR/ARM_CM85/secure/secure_port_macros.h +++ b/portable/IAR/ARM_CM85/secure/secure_port_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S index 80d5a1c63..d2cb78e92 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,12 +47,11 @@ MPU_xTaskDelayUntil: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv: - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil /*-----------------------------------------------------------*/ @@ -61,12 +60,11 @@ MPU_xTaskAbortDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv: - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay /*-----------------------------------------------------------*/ @@ -75,12 +73,11 @@ MPU_vTaskDelay: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv: - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskDelay /*-----------------------------------------------------------*/ @@ -89,12 +86,11 @@ MPU_uxTaskPriorityGet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv: - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet /*-----------------------------------------------------------*/ @@ -103,12 +99,11 @@ MPU_eTaskGetState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv: - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv: - pop {r0} svc #SYSTEM_CALL_eTaskGetState /*-----------------------------------------------------------*/ @@ -117,12 +112,11 @@ MPU_vTaskGetInfo: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv: - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo /*-----------------------------------------------------------*/ @@ -131,12 +125,11 @@ MPU_xTaskGetIdleTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv: - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle /*-----------------------------------------------------------*/ @@ -145,12 +138,11 @@ MPU_vTaskSuspend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv: - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSuspend /*-----------------------------------------------------------*/ @@ -159,12 +151,11 @@ MPU_vTaskResume: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv: - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskResume /*-----------------------------------------------------------*/ @@ -173,12 +164,11 @@ MPU_xTaskGetTickCount: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv: - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount /*-----------------------------------------------------------*/ @@ -187,12 +177,11 @@ MPU_uxTaskGetNumberOfTasks: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv: - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks /*-----------------------------------------------------------*/ @@ -201,12 +190,11 @@ MPU_ulTaskGetRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter /*-----------------------------------------------------------*/ @@ -215,12 +203,11 @@ MPU_ulTaskGetRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent /*-----------------------------------------------------------*/ @@ -229,12 +216,11 @@ MPU_ulTaskGetIdleRunTimePercent: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent /*-----------------------------------------------------------*/ @@ -243,12 +229,11 @@ MPU_ulTaskGetIdleRunTimeCounter: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv: - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter /*-----------------------------------------------------------*/ @@ -257,12 +242,11 @@ MPU_vTaskSetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv: - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -271,12 +255,11 @@ MPU_xTaskGetApplicationTaskTag: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv: - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag /*-----------------------------------------------------------*/ @@ -285,12 +268,11 @@ MPU_vTaskSetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -299,12 +281,11 @@ MPU_pvTaskGetThreadLocalStoragePointer: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv: - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer /*-----------------------------------------------------------*/ @@ -313,12 +294,11 @@ MPU_uxTaskGetSystemState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv: - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState /*-----------------------------------------------------------*/ @@ -327,12 +307,11 @@ MPU_uxTaskGetStackHighWaterMark: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark /*-----------------------------------------------------------*/ @@ -341,12 +320,11 @@ MPU_uxTaskGetStackHighWaterMark2: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv: - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 /*-----------------------------------------------------------*/ @@ -355,12 +333,11 @@ MPU_xTaskGetCurrentTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv: - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle /*-----------------------------------------------------------*/ @@ -369,12 +346,11 @@ MPU_xTaskGetSchedulerState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv: - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState /*-----------------------------------------------------------*/ @@ -383,12 +359,11 @@ MPU_vTaskSetTimeOutState: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv: - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState /*-----------------------------------------------------------*/ @@ -397,12 +372,11 @@ MPU_xTaskCheckForTimeOut: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv: - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut /*-----------------------------------------------------------*/ @@ -411,12 +385,11 @@ MPU_xTaskGenericNotifyEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv: - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify /*-----------------------------------------------------------*/ @@ -425,12 +398,11 @@ MPU_xTaskGenericNotifyWaitEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv: - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait /*-----------------------------------------------------------*/ @@ -439,12 +411,11 @@ MPU_ulTaskGenericNotifyTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv: - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake /*-----------------------------------------------------------*/ @@ -453,12 +424,11 @@ MPU_xTaskGenericNotifyStateClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv: - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear /*-----------------------------------------------------------*/ @@ -467,12 +437,11 @@ MPU_ulTaskGenericNotifyValueClear: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv: - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv: - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear /*-----------------------------------------------------------*/ @@ -481,12 +450,11 @@ MPU_xQueueGenericSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv: - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend /*-----------------------------------------------------------*/ @@ -495,12 +463,11 @@ MPU_uxQueueMessagesWaiting: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv: - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting /*-----------------------------------------------------------*/ @@ -509,12 +476,11 @@ MPU_uxQueueSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv: - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable /*-----------------------------------------------------------*/ @@ -523,12 +489,11 @@ MPU_xQueueReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv: - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueReceive /*-----------------------------------------------------------*/ @@ -537,12 +502,11 @@ MPU_xQueuePeek: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv: - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueuePeek /*-----------------------------------------------------------*/ @@ -551,12 +515,11 @@ MPU_xQueueSemaphoreTake: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv: - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake /*-----------------------------------------------------------*/ @@ -565,12 +528,11 @@ MPU_xQueueGetMutexHolder: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv: - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder /*-----------------------------------------------------------*/ @@ -579,12 +541,11 @@ MPU_xQueueTakeMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv: - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive /*-----------------------------------------------------------*/ @@ -593,12 +554,11 @@ MPU_xQueueGiveMutexRecursive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv: - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive /*-----------------------------------------------------------*/ @@ -607,12 +567,11 @@ MPU_xQueueSelectFromSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv: - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet /*-----------------------------------------------------------*/ @@ -621,12 +580,11 @@ MPU_xQueueAddToSet: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv: - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv: - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet /*-----------------------------------------------------------*/ @@ -635,12 +593,11 @@ MPU_vQueueAddToRegistry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv: - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry /*-----------------------------------------------------------*/ @@ -649,12 +606,11 @@ MPU_vQueueUnregisterQueue: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv: - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv: - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue /*-----------------------------------------------------------*/ @@ -663,12 +619,11 @@ MPU_pcQueueGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv: - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcQueueGetName /*-----------------------------------------------------------*/ @@ -677,12 +632,11 @@ MPU_pvTimerGetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv: - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID /*-----------------------------------------------------------*/ @@ -691,12 +645,11 @@ MPU_vTimerSetTimerID: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv: - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID /*-----------------------------------------------------------*/ @@ -705,12 +658,11 @@ MPU_xTimerIsTimerActive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv: - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive /*-----------------------------------------------------------*/ @@ -719,12 +671,11 @@ MPU_xTimerGetTimerDaemonTaskHandle: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv: - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle /*-----------------------------------------------------------*/ @@ -733,12 +684,11 @@ MPU_xTimerGenericCommandFromTaskEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv: - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask /*-----------------------------------------------------------*/ @@ -747,12 +697,11 @@ MPU_pcTimerGetName: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv: - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv: - pop {r0} svc #SYSTEM_CALL_pcTimerGetName /*-----------------------------------------------------------*/ @@ -761,12 +710,11 @@ MPU_vTimerSetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv: - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode /*-----------------------------------------------------------*/ @@ -775,12 +723,11 @@ MPU_xTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv: - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -789,12 +736,11 @@ MPU_uxTimerGetReloadMode: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv: - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode /*-----------------------------------------------------------*/ @@ -803,12 +749,11 @@ MPU_xTimerGetPeriod: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv: - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod /*-----------------------------------------------------------*/ @@ -817,12 +762,11 @@ MPU_xTimerGetExpiryTime: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv: - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv: - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime /*-----------------------------------------------------------*/ @@ -831,12 +775,11 @@ MPU_xEventGroupWaitBitsEntry: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv: - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits /*-----------------------------------------------------------*/ @@ -845,12 +788,11 @@ MPU_xEventGroupClearBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv: - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits /*-----------------------------------------------------------*/ @@ -859,12 +801,11 @@ MPU_xEventGroupSetBits: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv: - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits /*-----------------------------------------------------------*/ @@ -873,12 +814,11 @@ MPU_xEventGroupSync: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv: - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv: - pop {r0} svc #SYSTEM_CALL_xEventGroupSync /*-----------------------------------------------------------*/ @@ -887,12 +827,11 @@ MPU_uxEventGroupGetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv: - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber /*-----------------------------------------------------------*/ @@ -901,12 +840,11 @@ MPU_vEventGroupSetNumber: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv: - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv: - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber /*-----------------------------------------------------------*/ @@ -915,12 +853,11 @@ MPU_xStreamBufferSend: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv: - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend /*-----------------------------------------------------------*/ @@ -929,12 +866,11 @@ MPU_xStreamBufferReceive: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv: - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive /*-----------------------------------------------------------*/ @@ -943,12 +879,11 @@ MPU_xStreamBufferIsFull: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv: - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull /*-----------------------------------------------------------*/ @@ -957,12 +892,11 @@ MPU_xStreamBufferIsEmpty: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv: - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty /*-----------------------------------------------------------*/ @@ -971,12 +905,11 @@ MPU_xStreamBufferSpacesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv: - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable /*-----------------------------------------------------------*/ @@ -985,12 +918,11 @@ MPU_xStreamBufferBytesAvailable: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv: - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable /*-----------------------------------------------------------*/ @@ -999,12 +931,11 @@ MPU_xStreamBufferSetTriggerLevel: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv: - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel /*-----------------------------------------------------------*/ @@ -1013,12 +944,11 @@ MPU_xStreamBufferNextMessageLengthBytes: push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv: - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv: - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index a5ed7004a..76d2b2445 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -142,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 ) @@ -225,14 +228,18 @@ typedef void ( * portISR_t )( void ); #define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#if ( portARMV8M_MINOR_VERSION >= 1 ) + + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) +#endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) - -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -281,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 */ @@ -367,6 +374,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ /** @@ -375,35 +396,55 @@ typedef void ( * portISR_t )( void ); */ static void prvTaskExitError( void ); -#if ( configENABLE_MPU == 1 ) +#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 */ +#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. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -447,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; @@ -463,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; @@ -486,24 +527,24 @@ 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 */ /*-----------------------------------------------------------*/ -#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#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 +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /** * @brief Each task maintains its own interrupt status in the critical nesting @@ -513,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 */ @@ -535,26 +576,27 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configUSE_TICKLESS_IDLE == 1 ) + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; @@ -770,6 +812,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; __asm volatile ( "cpsie i" ::: "memory" ); } } + #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -826,7 +869,8 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ { uint32_t ulAccessPermissions = 0; @@ -843,10 +887,12 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU */ + +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { #if defined( __ARMCC_VERSION ) @@ -876,69 +922,64 @@ 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 */ /*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 ) + static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */ { #if ( configENABLE_TRUSTZONE == 1 ) @@ -960,6 +1001,7 @@ static void prvTaskExitError( void ) * LSPEN = 1 ==> Enable lazy context save of FP state. */ *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK ); } + #endif /* configENABLE_FPU */ /*-----------------------------------------------------------*/ @@ -1056,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 ) @@ -1122,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. */ @@ -1158,9 +1200,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1193,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. */ @@ -1208,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 ]; } @@ -1231,6 +1278,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1249,13 +1297,14 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; /* 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. */ @@ -1305,9 +1354,10 @@ 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 ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1336,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. */ @@ -1351,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 ]; } @@ -1443,6 +1497,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1461,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 ) @@ -1486,19 +1541,27 @@ 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 ) ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1522,6 +1585,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1536,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. */ @@ -1558,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 ) { @@ -1604,6 +1681,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1613,7 +1704,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ { /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler * for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -1636,7 +1727,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -1726,6 +1817,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void ) prvConfigurePACBTI( pdTRUE ); + } + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -1740,11 +1839,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /* Start the first task. */ vStartFirstTask(); @@ -1772,10 +1871,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; int32_t lIndex = 0; @@ -1800,10 +1900,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that * the stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; - ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1; + ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1; /* If the stack is within the privileged SRAM, do not protect it * using a separate MPU region. This is needed because privileged @@ -1871,6 +1971,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) | ( portMPU_RLAR_REGION_ENABLE ); + /* PXN. */ + #if ( portARMV8M_MINOR_VERSION >= 1 ) + { + if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 ) + { + xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ); + } + } + #endif /* portARMV8M_MINOR_VERSION >= 1 */ + /* Normal memory/ Device memory. */ if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 ) { @@ -1893,10 +2003,12 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ lIndex++; } } + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ -#if ( configENABLE_MPU == 1 ) +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ @@ -1906,7 +2018,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } @@ -1941,7 +2061,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ return xAccessGranted; } -#endif /* configENABLE_MPU */ + +#endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ BaseType_t xPortIsInsideInterrupt( void ) @@ -2005,7 +2126,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } @@ -2122,3 +2243,38 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + + #if ( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if ( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h index ecd86b97f..b7021b024 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s index 7cf467d22..ba6e8e915 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -140,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -163,10 +173,20 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +219,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -230,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -239,11 +258,20 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -297,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -332,12 +368,21 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ +#if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -348,6 +393,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h index cffcb20d9..ff5c9895d 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -55,6 +55,7 @@ */ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 +#define portARMV8M_MINOR_VERSION 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ @@ -62,11 +63,6 @@ #include "portmacrocommon.h" /*-----------------------------------------------------------*/ -#if ( configTOTAL_MPU_REGIONS == 16 ) - #error 16 MPU regions are not yet supported for this port. -#endif -/*-----------------------------------------------------------*/ - /** * @brief Critical section management. */ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 672b0dbdc..f373bcad5 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + + /** + * @brief Generates 128-bit task's random PAC key. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -137,7 +151,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +232,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ + /* + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><-----------><----> + * 16 17 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 71 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 17 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 55 + + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 17 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 70 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 17 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ - -/* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ - #define MAX_CONTEXT_SIZE 53 - - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS @@ -312,7 +378,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P * @brief Validate priority of ISRs that are allowed to call FreeRTOS * system calls. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() diff --git a/portable/IAR/ARM_CRx_No_GIC/port.c b/portable/IAR/ARM_CRx_No_GIC/port.c index 235585642..1b5c0fb8e 100644 --- a/portable/IAR/ARM_CRx_No_GIC/port.c +++ b/portable/IAR/ARM_CRx_No_GIC/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ARM_CRx_No_GIC/portASM.s b/portable/IAR/ARM_CRx_No_GIC/portASM.s index 6883cced4..f37ad570b 100644 --- a/portable/IAR/ARM_CRx_No_GIC/portASM.s +++ b/portable/IAR/ARM_CRx_No_GIC/portASM.s @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * @@ -215,7 +215,7 @@ exit_without_switch: MOVS PC, LR switch_before_exit: - /* A context swtich is to be performed. Clear the context switch pending + /* A context switch is to be performed. Clear the context switch pending flag. */ MOV r0, #0 STR r0, [r1] diff --git a/portable/IAR/ARM_CRx_No_GIC/portmacro.h b/portable/IAR/ARM_CRx_No_GIC/portmacro.h index d7c18b1f7..7707fcf02 100644 --- a/portable/IAR/ARM_CRx_No_GIC/portmacro.h +++ b/portable/IAR/ARM_CRx_No_GIC/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ATMega323/port.c b/portable/IAR/ATMega323/port.c index 991713789..980787990 100644 --- a/portable/IAR/ATMega323/port.c +++ b/portable/IAR/ATMega323/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ATMega323/portmacro.h b/portable/IAR/ATMega323/portmacro.h index 0a870ae21..e50d9f3d7 100644 --- a/portable/IAR/ATMega323/portmacro.h +++ b/portable/IAR/ATMega323/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/ATMega323/portmacro.s90 b/portable/IAR/ATMega323/portmacro.s90 index 8c72f410f..029d0dbb6 100644 --- a/portable/IAR/ATMega323/portmacro.s90 +++ b/portable/IAR/ATMega323/portmacro.s90 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/AVR32_UC3/exception.s82 b/portable/IAR/AVR32_UC3/exception.s82 index 12012e420..653600995 100644 --- a/portable/IAR/AVR32_UC3/exception.s82 +++ b/portable/IAR/AVR32_UC3/exception.s82 @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * diff --git a/portable/IAR/AVR32_UC3/port.c b/portable/IAR/AVR32_UC3/port.c index 94fa1e37a..dbe121cca 100644 --- a/portable/IAR/AVR32_UC3/port.c +++ b/portable/IAR/AVR32_UC3/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * @@ -374,7 +374,7 @@ static void prvSetupTimerInterrupt( void ) #if ( configTICK_USE_TC == 1 ) volatile avr32_tc_t * tc = &AVR32_TC; - /* Options for waveform genration. */ + /* Options for waveform generation. */ tc_waveform_opt_t waveform_opt = { .channel = configTICK_TC_CHANNEL, /* Channel selection. */ diff --git a/portable/IAR/AVR32_UC3/portmacro.h b/portable/IAR/AVR32_UC3/portmacro.h index 42f4bfe65..036833f8f 100644 --- a/portable/IAR/AVR32_UC3/portmacro.h +++ b/portable/IAR/AVR32_UC3/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * diff --git a/portable/IAR/AVR32_UC3/read.c b/portable/IAR/AVR32_UC3/read.c index bbdc0781b..639d1f8f8 100644 --- a/portable/IAR/AVR32_UC3/read.c +++ b/portable/IAR/AVR32_UC3/read.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * diff --git a/portable/IAR/AVR32_UC3/write.c b/portable/IAR/AVR32_UC3/write.c index 139f45277..5ac796332 100644 --- a/portable/IAR/AVR32_UC3/write.c +++ b/portable/IAR/AVR32_UC3/write.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT AND BSD-3-Clause * diff --git a/portable/IAR/AVR_AVRDx/port.c b/portable/IAR/AVR_AVRDx/port.c index 8d8f22331..07269f0f6 100644 --- a/portable/IAR/AVR_AVRDx/port.c +++ b/portable/IAR/AVR_AVRDx/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AVR_AVRDx/porthardware.h b/portable/IAR/AVR_AVRDx/porthardware.h index c313e0c69..f9176f96b 100644 --- a/portable/IAR/AVR_AVRDx/porthardware.h +++ b/portable/IAR/AVR_AVRDx/porthardware.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AVR_AVRDx/portmacro.h b/portable/IAR/AVR_AVRDx/portmacro.h index 13c3f6e6b..829958dc0 100644 --- a/portable/IAR/AVR_AVRDx/portmacro.h +++ b/portable/IAR/AVR_AVRDx/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AVR_AVRDx/portmacro.s90 b/portable/IAR/AVR_AVRDx/portmacro.s90 index dc72ccf58..c518d3af9 100644 --- a/portable/IAR/AVR_AVRDx/portmacro.s90 +++ b/portable/IAR/AVR_AVRDx/portmacro.s90 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/AVR_Mega0/port.c b/portable/IAR/AVR_Mega0/port.c index 4dc8ab3c3..7d1d2f6e8 100644 --- a/portable/IAR/AVR_Mega0/port.c +++ b/portable/IAR/AVR_Mega0/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AVR_Mega0/porthardware.h b/portable/IAR/AVR_Mega0/porthardware.h index c7341447c..d834a8e82 100644 --- a/portable/IAR/AVR_Mega0/porthardware.h +++ b/portable/IAR/AVR_Mega0/porthardware.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AVR_Mega0/portmacro.h b/portable/IAR/AVR_Mega0/portmacro.h index 13c3f6e6b..829958dc0 100644 --- a/portable/IAR/AVR_Mega0/portmacro.h +++ b/portable/IAR/AVR_Mega0/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AVR_Mega0/portmacro.s90 b/portable/IAR/AVR_Mega0/portmacro.s90 index 2e5046325..c2789d48e 100644 --- a/portable/IAR/AVR_Mega0/portmacro.s90 +++ b/portable/IAR/AVR_Mega0/portmacro.s90 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h b/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h index 2dbceba43..6df767884 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h @@ -562,8 +562,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h b/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h index 9d95f3eb7..a39150071 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h @@ -487,8 +487,8 @@ /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( 0x1 << 8 ) /* (MC) Half-word */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h index b8a7652f4..a143430db 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h index fe701970e..78ea37595 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h @@ -411,8 +411,8 @@ /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( 0x1 << 8 ) /* (MC) Half-word */ @@ -1234,7 +1234,7 @@ #define EMAC_ECOL ( 96 ) /* Excessive Collision Register */ #define EMAC_TUND ( 100 ) /* Transmit Underrun Error Register */ #define EMAC_CSE ( 104 ) /* Carrier Sense Error Register */ -#define EMAC_RRE ( 108 ) /* Receive Ressource Error Register */ +#define EMAC_RRE ( 108 ) /* Receive Resource Error Register */ #define EMAC_ROV ( 112 ) /* Receive Overrun Errors Register */ #define EMAC_RSE ( 116 ) /* Receive Symbol Errors Register */ #define EMAC_ELE ( 120 ) /* Excessive Length Errors Register */ @@ -2096,7 +2096,7 @@ #define AT91C_EMAC_SA1H ( 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h index 98e1babc2..f51209974 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h index 5c0be5efc..8471ca44d 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h @@ -411,8 +411,8 @@ /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( 0x1 << 8 ) /* (MC) Half-word */ @@ -1234,7 +1234,7 @@ #define EMAC_ECOL ( 96 ) /* Excessive Collision Register */ #define EMAC_TUND ( 100 ) /* Transmit Underrun Error Register */ #define EMAC_CSE ( 104 ) /* Carrier Sense Error Register */ -#define EMAC_RRE ( 108 ) /* Receive Ressource Error Register */ +#define EMAC_RRE ( 108 ) /* Receive Resource Error Register */ #define EMAC_ROV ( 112 ) /* Receive Overrun Errors Register */ #define EMAC_RSE ( 116 ) /* Receive Symbol Errors Register */ #define EMAC_ELE ( 120 ) /* Excessive Length Errors Register */ @@ -2096,7 +2096,7 @@ #define AT91C_EMAC_SA1H ( 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/ISR_Support.h b/portable/IAR/AtmelSAM7S64/ISR_Support.h index d63e908b9..273e95141 100644 --- a/portable/IAR/AtmelSAM7S64/ISR_Support.h +++ b/portable/IAR/AtmelSAM7S64/ISR_Support.h @@ -1,6 +1,6 @@ ; /* * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * ; * * ; * SPDX-License-Identifier: MIT * ; * diff --git a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h index a392be1a7..c53e6c8af 100644 --- a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h +++ b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h @@ -60,7 +60,7 @@ __inline void AT91F_MC_EFC_CfgModeReg( AT91PS_MC pMC, /* pointer to a MC co /**---------------------------------------------------------------------------- */ /** \fn AT91F_MC_EFC_GetModeReg */ -/** \brief Return MC EFC Mode Regsiter */ +/** \brief Return MC EFC Mode Register */ /**---------------------------------------------------------------------------- */ __inline unsigned int AT91F_MC_EFC_GetModeReg( AT91PS_MC pMC ) /* pointer to a MC controller */ { @@ -69,7 +69,7 @@ __inline unsigned int AT91F_MC_EFC_GetModeReg( AT91PS_MC pMC ) /* pointer to a M /**---------------------------------------------------------------------------- */ /** \fn AT91F_MC_EFC_ComputeFMCN */ -/** \brief Return MC EFC Mode Regsiter */ +/** \brief Return MC EFC Mode Register */ /**---------------------------------------------------------------------------- */ __inline unsigned int AT91F_MC_EFC_ComputeFMCN( int master_clock ) /* master clock in Hz */ { @@ -123,7 +123,7 @@ __inline unsigned int AT91F_MC_EFC_IsInterruptSet( AT91PS_MC pMC, /* \arg /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -135,7 +135,7 @@ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -147,7 +147,7 @@ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -159,7 +159,7 @@ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC con /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; @@ -742,7 +742,7 @@ __inline unsigned int AT91F_SPI_SendFrame( AT91PS_SPI pSPI, /**---------------------------------------------------------------------------- */ /** \fn AT91F_SPI_Close */ -/** \brief Close SPI: disable IT disable transfert, close PDC */ +/** \brief Close SPI: disable IT disable transfer, close PDC */ /**---------------------------------------------------------------------------- */ __inline void AT91F_SPI_Close( AT91PS_SPI pSPI ) /* \arg pointer to a SPI controller */ { @@ -1063,7 +1063,7 @@ __inline void AT91F_CKGR_DisableMainOscillator( AT91PS_CKGR pCKGR ) /* \arg poin /**---------------------------------------------------------------------------- */ /** \fn AT91F_CKGR_CfgMainOscStartUpTime */ -/** \brief Cfg MOR Register according to the main osc startup time */ +/** \brief Cfg MORE Register according to the main osc startup time */ /**---------------------------------------------------------------------------- */ __inline void AT91F_CKGR_CfgMainOscStartUpTime( AT91PS_CKGR pCKGR, /* \arg pointer to CKGR controller */ unsigned int startup_time, /* \arg main osc startup time in microsecond (us) */ diff --git a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h index 61fbb1f79..4fc975894 100644 --- a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h +++ b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h @@ -210,7 +210,7 @@ /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -222,7 +222,7 @@ /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -234,7 +234,7 @@ /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -246,7 +246,7 @@ /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; @@ -1054,7 +1054,7 @@ /**---------------------------------------------------------------------------- */ /** \fn AT91F_CKGR_CfgMainOscStartUpTime */ -/** \brief Cfg MOR Register according to the main osc startup time */ +/** \brief Cfg MORE Register according to the main osc startup time */ /**---------------------------------------------------------------------------- */ __inline void AT91F_CKGR_CfgMainOscStartUpTime( AT91PS_CKGR pCKGR, /* \arg pointer to CKGR controller */ unsigned int startup_time, /* \arg main osc startup time in microsecond (us) */ diff --git a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h index 0d9a70884..4ac85fb96 100644 --- a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h +++ b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h @@ -210,7 +210,7 @@ /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -222,7 +222,7 @@ /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -234,7 +234,7 @@ /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -246,7 +246,7 @@ /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; @@ -1054,7 +1054,7 @@ /**---------------------------------------------------------------------------- */ /** \fn AT91F_CKGR_CfgMainOscStartUpTime */ -/** \brief Cfg MOR Register according to the main osc startup time */ +/** \brief Cfg MORE Register according to the main osc startup time */ /**---------------------------------------------------------------------------- */ __inline void AT91F_CKGR_CfgMainOscStartUpTime( AT91PS_CKGR pCKGR, /* \arg pointer to CKGR controller */ unsigned int startup_time, /* \arg main osc startup time in microsecond (us) */ diff --git a/portable/IAR/AtmelSAM7S64/port.c b/portable/IAR/AtmelSAM7S64/port.c index ba72aa804..5f5f7625f 100644 --- a/portable/IAR/AtmelSAM7S64/port.c +++ b/portable/IAR/AtmelSAM7S64/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AtmelSAM7S64/portasm.s79 b/portable/IAR/AtmelSAM7S64/portasm.s79 index b01bcf548..4f5f5c083 100644 --- a/portable/IAR/AtmelSAM7S64/portasm.s79 +++ b/portable/IAR/AtmelSAM7S64/portasm.s79 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/AtmelSAM7S64/portmacro.h b/portable/IAR/AtmelSAM7S64/portmacro.h index 337139712..75588d526 100644 --- a/portable/IAR/AtmelSAM7S64/portmacro.h +++ b/portable/IAR/AtmelSAM7S64/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AtmelSAM9XE/ISR_Support.h b/portable/IAR/AtmelSAM9XE/ISR_Support.h index e22768d7d..ac73c7816 100644 --- a/portable/IAR/AtmelSAM9XE/ISR_Support.h +++ b/portable/IAR/AtmelSAM9XE/ISR_Support.h @@ -1,6 +1,6 @@ ; /* * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * ; * * ; * SPDX-License-Identifier: MIT * ; * diff --git a/portable/IAR/AtmelSAM9XE/port.c b/portable/IAR/AtmelSAM9XE/port.c index 20c59b71f..f2bd893fc 100644 --- a/portable/IAR/AtmelSAM9XE/port.c +++ b/portable/IAR/AtmelSAM9XE/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/AtmelSAM9XE/portasm.s79 b/portable/IAR/AtmelSAM9XE/portasm.s79 index d3434ecca..37241da9c 100644 --- a/portable/IAR/AtmelSAM9XE/portasm.s79 +++ b/portable/IAR/AtmelSAM9XE/portasm.s79 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/AtmelSAM9XE/portmacro.h b/portable/IAR/AtmelSAM9XE/portmacro.h index 6a234933e..68e54c8d3 100644 --- a/portable/IAR/AtmelSAM9XE/portmacro.h +++ b/portable/IAR/AtmelSAM9XE/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/LPC2000/ISR_Support.h b/portable/IAR/LPC2000/ISR_Support.h index d63e908b9..273e95141 100644 --- a/portable/IAR/LPC2000/ISR_Support.h +++ b/portable/IAR/LPC2000/ISR_Support.h @@ -1,6 +1,6 @@ ; /* * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * ; * * ; * SPDX-License-Identifier: MIT * ; * diff --git a/portable/IAR/LPC2000/port.c b/portable/IAR/LPC2000/port.c index a8cf766ab..69d711d3b 100644 --- a/portable/IAR/LPC2000/port.c +++ b/portable/IAR/LPC2000/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/LPC2000/portasm.s79 b/portable/IAR/LPC2000/portasm.s79 index eb1793315..2bd1ccc06 100644 --- a/portable/IAR/LPC2000/portasm.s79 +++ b/portable/IAR/LPC2000/portasm.s79 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/LPC2000/portmacro.h b/portable/IAR/LPC2000/portmacro.h index 40231e408..b44d307f3 100644 --- a/portable/IAR/LPC2000/portmacro.h +++ b/portable/IAR/LPC2000/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/MSP430/port.c b/portable/IAR/MSP430/port.c index 845943c7f..070f64bf0 100644 --- a/portable/IAR/MSP430/port.c +++ b/portable/IAR/MSP430/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/MSP430/portasm.h b/portable/IAR/MSP430/portasm.h index a9d49b7ff..0d8115034 100644 --- a/portable/IAR/MSP430/portasm.h +++ b/portable/IAR/MSP430/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -31,54 +31,54 @@ portSAVE_CONTEXT macro -IMPORT pxCurrentTCB -IMPORT usCriticalNesting + IMPORT pxCurrentTCB + IMPORT usCriticalNesting -/* Save the remaining registers. */ -push r4 -push r5 -push r6 -push r7 -push r8 -push r9 -push r10 -push r11 -push r12 -push r13 -push r14 -push r15 -mov.w &usCriticalNesting, r14 -push r14 - mov.w &pxCurrentTCB, r12 - mov.w r1, 0 ( r12 ) -endm + /* Save the remaining registers. */ + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + mov.w &usCriticalNesting, r14 + push r14 + mov.w &pxCurrentTCB, r12 + mov.w r1, 0(r12) + endm /*-----------------------------------------------------------*/ portRESTORE_CONTEXT macro -mov.w & pxCurrentTCB, r12 -mov.w @r12, r1 -pop r15 -mov.w r15, &usCriticalNesting -pop r15 -pop r14 -pop r13 -pop r12 -pop r11 -pop r10 -pop r9 -pop r8 -pop r7 -pop r6 -pop r5 -pop r4 + mov.w &pxCurrentTCB, r12 + mov.w @r12, r1 + pop r15 + mov.w r15, &usCriticalNesting + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 -/* The last thing on the stack will be the status register. - * Ensure the power down bits are clear ready for the next - * time this power down register is popped from the stack. */ -bic.w # 0xf0, 0 ( SP ) + /* The last thing on the stack will be the status register. + * Ensure the power down bits are clear ready for the next + * time this power down register is popped from the stack. */ + bic.w #0xf0, 0(SP) -reti -endm + reti + endm /*-----------------------------------------------------------*/ #endif /* ifndef PORTASM_H */ diff --git a/portable/IAR/MSP430/portext.s43 b/portable/IAR/MSP430/portext.s43 index 5360a9700..bfe6a190f 100644 --- a/portable/IAR/MSP430/portext.s43 +++ b/portable/IAR/MSP430/portext.s43 @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/MSP430/portmacro.h b/portable/IAR/MSP430/portmacro.h index 51b8aad1e..f87bfe589 100644 --- a/portable/IAR/MSP430/portmacro.h +++ b/portable/IAR/MSP430/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/MSP430X/data_model.h b/portable/IAR/MSP430X/data_model.h index 97931f3b5..0d5dcbdd4 100644 --- a/portable/IAR/MSP430X/data_model.h +++ b/portable/IAR/MSP430X/data_model.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/MSP430X/port.c b/portable/IAR/MSP430X/port.c index 920f0796f..6c5b21c3a 100644 --- a/portable/IAR/MSP430X/port.c +++ b/portable/IAR/MSP430X/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -30,6 +30,9 @@ #include "FreeRTOS.h" #include "task.h" +/* Hardware includes. */ +#include "msp430.h" + /*----------------------------------------------------------- * Implementation of functions defined in portable.h for the MSP430X port. *----------------------------------------------------------*/ diff --git a/portable/IAR/MSP430X/portext.s43 b/portable/IAR/MSP430X/portext.s43 index cc2f592a3..ccfd084c2 100644 --- a/portable/IAR/MSP430X/portext.s43 +++ b/portable/IAR/MSP430X/portext.s43 @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/MSP430X/portmacro.h b/portable/IAR/MSP430X/portmacro.h index bac91e8a4..b428f8d40 100644 --- a/portable/IAR/MSP430X/portmacro.h +++ b/portable/IAR/MSP430X/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -39,9 +39,6 @@ *----------------------------------------------------------- */ -/* Hardware includes. */ -#include "msp430.h" - /* Type definitions. */ #define portCHAR char #define portFLOAT float @@ -75,8 +72,8 @@ typedef unsigned short UBaseType_t; /*-----------------------------------------------------------*/ /* Interrupt control macros. */ -#define portDISABLE_INTERRUPTS() _DINT(); _NOP() -#define portENABLE_INTERRUPTS() _EINT(); _NOP() +#define portDISABLE_INTERRUPTS() __asm volatile ( "DINT\n" "NOP" ) +#define portENABLE_INTERRUPTS() __asm volatile ( "NOP\n" "EINT\n" "NOP" ) /*-----------------------------------------------------------*/ /* Critical section control macros. */ @@ -126,7 +123,7 @@ extern void vPortYield( void ); #define portBYTE_ALIGNMENT 2 #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portNOP() __no_operation() +#define portNOP() __asm volatile ( "NOP" ) /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ diff --git a/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h index 01100f0a9..364fd5773 100644 --- a/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RISC-V/port.c b/portable/IAR/RISC-V/port.c index ce0cbdf2f..820423ec5 100644 --- a/portable/IAR/RISC-V/port.c +++ b/portable/IAR/RISC-V/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -27,8 +27,8 @@ */ /*----------------------------------------------------------- -* Implementation of functions defined in portable.h for the RISC-V port. -*----------------------------------------------------------*/ + * Implementation of functions defined in portable.h for the RISC-V port. + *----------------------------------------------------------*/ /* Scheduler includes. */ #include "FreeRTOS.h" @@ -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. */ -uint32_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/RISC-V/portASM.s b/portable/IAR/RISC-V/portASM.s index 005b0eb90..12a2a6154 100644 --- a/portable/IAR/RISC-V/portASM.s +++ b/portable/IAR/RISC-V/portASM.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -147,7 +147,7 @@ portUPDATE_MTIMER_COMPARE_REGISTER MACRO * for the function is as per the other ports: * StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ); * - * As per the standard RISC-V ABI pxTopcOfStack is passed in in a0, pxCode in + * As per the standard RISC-V ABI pxTopOfStack is passed in in a0, pxCode in * a1, and pvParameters in a2. The new top of stack is passed out in a0. * * RISC-V maps registers to ABI names as follows (X1 to X31 integer registers @@ -167,7 +167,7 @@ portUPDATE_MTIMER_COMPARE_REGISTER MACRO * x18-27 s2-11 Saved registers Callee * x28-31 t3-6 Temporaries Caller * - * The RISC-V context is saved t FreeRTOS tasks in the following stack frame, + * The RISC-V context is saved to FreeRTOS tasks in the following stack frame, * where the global and thread pointers are currently assumed to be constant so * are not saved: * diff --git a/portable/IAR/RISC-V/portContext.h b/portable/IAR/RISC-V/portContext.h index 35bca7fe5..7b3244e7b 100644 --- a/portable/IAR/RISC-V/portContext.h +++ b/portable/IAR/RISC-V/portContext.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RISC-V/portmacro.h b/portable/IAR/RISC-V/portmacro.h index eba9eb6f2..c7237b363 100644 --- a/portable/IAR/RISC-V/portmacro.h +++ b/portable/IAR/RISC-V/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -113,9 +113,6 @@ extern void vTaskSwitchContext( void ); /* Critical section management. */ #define portCRITICAL_NESTING_IN_TCB 0 -#define portSET_INTERRUPT_MASK_FROM_ISR() 0 -#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue - #define portDISABLE_INTERRUPTS() __disable_interrupt() #define portENABLE_INTERRUPTS() __enable_interrupt() diff --git a/portable/IAR/RL78/port.c b/portable/IAR/RL78/port.c index 55baa43e7..656efeb2d 100644 --- a/portable/IAR/RL78/port.c +++ b/portable/IAR/RL78/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -93,12 +93,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, void * pvParameters ) { uint32_t * pulLocal; - - /* With large code and large data sizeof( StackType_t ) == 2, and - * sizeof( StackType_t * ) == 4. With small code and small data - * sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */ - - #if __DATA_MODEL__ == __DATA_MODEL_FAR__ + /* With large data sizeof( StackType_t ) == 2, and + * sizeof( StackType_t * ) == 4. With small data + * sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */ +#if __DATA_MODEL__ == __DATA_MODEL_FAR__ { /* Far pointer parameters are passed using the A:DE registers (24-bit). * Although they are stored in memory as a 32-bit value. Hence decrement @@ -106,9 +104,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, * storing the pvParameters value. */ pxTopOfStack--; pulLocal = ( uint32_t * ) pxTopOfStack; - *pulLocal = ( uint32_t ) pvParameters; - pxTopOfStack--; - + #if __CALLING_CONVENTION__ == __CC_V2__ + /* V2: parameter via A:DE, do not push pvParameters on stack */ + #else + /* V1 or unknown: keep stack write */ + *pulLocal = ( uint32_t ) pvParameters; + pxTopOfStack--; + #endif /* The return address is a 32-bit value. So decrement the stack pointer * in order to make extra room needed to store the correct value. See the * comments above the prvTaskExitError() prototype at the top of this file. */ @@ -116,65 +118,89 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, pulLocal = ( uint32_t * ) pxTopOfStack; *pulLocal = ( uint32_t ) prvTaskExitError; pxTopOfStack--; - /* The task function start address combined with the PSW is also stored * as a 32-bit value. So leave a space for the second two bytes. */ pxTopOfStack--; pulLocal = ( uint32_t * ) pxTopOfStack; *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) ); pxTopOfStack--; - - /* An initial value for the AX register. */ - *pxTopOfStack = ( StackType_t ) 0x1111; + /* Register image on task entry. */ + #if __CALLING_CONVENTION__ == __CC_V2__ + { + uint32_t p = ( uint32_t ) pvParameters; + uint16_t de_init = (uint16_t)( p & 0xFFFFU ); + uint16_t ax_init = (uint16_t)( ((p >> 16) & 0xFFU) << 8 ); + /* AX register image */ + *pxTopOfStack = ( StackType_t ) ax_init; + pxTopOfStack--; + /* HL register image (dummy) */ + *pxTopOfStack = ( StackType_t ) 0x2222; + pxTopOfStack--; + /* CS:ES register image */ + *pxTopOfStack = ( StackType_t ) 0x0F00; + pxTopOfStack--; + /* DE register image */ + *pxTopOfStack = ( StackType_t ) de_init; + pxTopOfStack--; + } + #else + /* An initial value for the AX register. */ + *pxTopOfStack = ( StackType_t ) 0x1111; + pxTopOfStack--; + /* HL register image (dummy) */ + *pxTopOfStack = ( StackType_t ) 0x2222; + pxTopOfStack--; + /* CS:ES register image */ + *pxTopOfStack = ( StackType_t ) 0x0F00; + pxTopOfStack--; + /* DE register image (dummy) */ + *pxTopOfStack = ( StackType_t ) 0xDEDE; + pxTopOfStack--; + #endif + /* BC remains a dummy value (not used for parameter passing). */ + *pxTopOfStack = ( StackType_t ) 0xBCBC; pxTopOfStack--; } - #else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */ +#else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */ { - /* The return address, leaving space for the first two bytes of the + /* The return address, leaving space for the first two bytes of the * 32-bit value. See the comments above the prvTaskExitError() prototype * at the top of this file. */ pxTopOfStack--; pulLocal = ( uint32_t * ) pxTopOfStack; *pulLocal = ( uint32_t ) prvTaskExitError; pxTopOfStack--; - /* Task function. Again as it is written as a 32-bit value a space is * left on the stack for the second two bytes. */ pxTopOfStack--; - /* Task function start address combined with the PSW. */ pulLocal = ( uint32_t * ) pxTopOfStack; *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) ); pxTopOfStack--; - /* The parameter is passed in AX. */ *pxTopOfStack = ( StackType_t ) pvParameters; pxTopOfStack--; + /* An initial value for the HL register. */ + *pxTopOfStack = ( StackType_t ) 0x2222; + pxTopOfStack--; + /* CS and ES registers. */ + *pxTopOfStack = ( StackType_t ) 0x0F00; + pxTopOfStack--; + /* The remaining general purpose registers DE and BC */ + *pxTopOfStack = ( StackType_t ) 0xDEDE; + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0xBCBC; + pxTopOfStack--; } - #endif /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */ - - /* An initial value for the HL register. */ - *pxTopOfStack = ( StackType_t ) 0x2222; - pxTopOfStack--; - - /* CS and ES registers. */ - *pxTopOfStack = ( StackType_t ) 0x0F00; - pxTopOfStack--; - - /* The remaining general purpose registers DE and BC */ - *pxTopOfStack = ( StackType_t ) 0xDEDE; - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0xBCBC; - pxTopOfStack--; - +#endif /* __DATA_MODEL__ */ /* Finally the critical section nesting count is set to zero when the task * first starts. */ *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING; - /* Return a pointer to the top of the stack that has been generated so * it can be stored in the task control block for the task. */ return pxTopOfStack; } + /*-----------------------------------------------------------*/ static void prvTaskExitError( void ) diff --git a/portable/IAR/RL78/portasm.s b/portable/IAR/RL78/portasm.s index f328d1bec..7067cb1e4 100644 --- a/portable/IAR/RL78/portasm.s +++ b/portable/IAR/RL78/portasm.s @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/RL78/portmacro.h b/portable/IAR/RL78/portmacro.h index 4bf61e88f..36697a620 100644 --- a/portable/IAR/RL78/portmacro.h +++ b/portable/IAR/RL78/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -130,7 +130,18 @@ /* Task utilities. */ #define portNOP() __asm( "NOP" ) #define portYIELD() __asm( "BRK" ) - #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) do { if( xHigherPriorityTaskWoken ) vTaskSwitchContext( ); } while( 0 ) + #ifndef configREQUIRE_ASM_ISR_WRAPPER + #define configREQUIRE_ASM_ISR_WRAPPER 1 + #endif + #if( configREQUIRE_ASM_ISR_WRAPPER == 1 ) + /* You must implement an assembly ISR wrapper (see the below for details) if you need an ISR to cause a context switch. + * https://www.freertos.org/Documentation/02-Kernel/03-Supported-devices/04-Demos/Renesas/RTOS_RL78_IAR_Demos#writing-interrupt-service-routines */ + #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) do { if( xHigherPriorityTaskWoken != pdFALSE ) vTaskSwitchContext(); } while( 0 ) + #else + /* You must not implement an assembly ISR wrapper even if you need an ISR to cause a context switch. + * The portYIELD, which is similar to role of an assembly ISR wrapper, runs only when a context switch is required. */ + #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) do { if( xHigherPriorityTaskWoken != pdFALSE ) portYIELD(); } while( 0 ) + #endif /*-----------------------------------------------------------*/ /* Hardware specifics. */ @@ -176,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__ @@ -206,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/IAR/RX100/port.c b/portable/IAR/RX100/port.c index 27e5d4b75..b63b23b48 100644 --- a/portable/IAR/RX100/port.c +++ b/portable/IAR/RX100/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RX100/port_asm.s b/portable/IAR/RX100/port_asm.s index 224f4484a..5eb90f7d1 100644 --- a/portable/IAR/RX100/port_asm.s +++ b/portable/IAR/RX100/port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RX100/portmacro.h b/portable/IAR/RX100/portmacro.h index 2ea18f97a..ab5eae69f 100644 --- a/portable/IAR/RX100/portmacro.h +++ b/portable/IAR/RX100/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -108,7 +108,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( __get_interrupt_level() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( __get_interrupt_level() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/IAR/RX600/port.c b/portable/IAR/RX600/port.c index f59725bbd..73ff96cff 100644 --- a/portable/IAR/RX600/port.c +++ b/portable/IAR/RX600/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RX600/port_asm.s b/portable/IAR/RX600/port_asm.s index d6584264b..29698534d 100644 --- a/portable/IAR/RX600/port_asm.s +++ b/portable/IAR/RX600/port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RX600/portmacro.h b/portable/IAR/RX600/portmacro.h index 0a3659c92..87faf8639 100644 --- a/portable/IAR/RX600/portmacro.h +++ b/portable/IAR/RX600/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -110,7 +110,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( __get_interrupt_level() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( __get_interrupt_level() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/IAR/RX700v3_DPFPU/port.c b/portable/IAR/RX700v3_DPFPU/port.c index 2a902f28e..d05835975 100644 --- a/portable/IAR/RX700v3_DPFPU/port.c +++ b/portable/IAR/RX700v3_DPFPU/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RX700v3_DPFPU/portmacro.h b/portable/IAR/RX700v3_DPFPU/portmacro.h index 2819f62e5..e24cbfe53 100644 --- a/portable/IAR/RX700v3_DPFPU/portmacro.h +++ b/portable/IAR/RX700v3_DPFPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -143,7 +143,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( __get_interrupt_level() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( __get_interrupt_level() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/IAR/RXv2/port.c b/portable/IAR/RXv2/port.c index 2c87ba5af..af21ae57a 100644 --- a/portable/IAR/RXv2/port.c +++ b/portable/IAR/RXv2/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RXv2/port_asm.s b/portable/IAR/RXv2/port_asm.s index 6fe6c1d18..cbebcf31d 100644 --- a/portable/IAR/RXv2/port_asm.s +++ b/portable/IAR/RXv2/port_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/RXv2/portmacro.h b/portable/IAR/RXv2/portmacro.h index 512a6e594..792beb9df 100644 --- a/portable/IAR/RXv2/portmacro.h +++ b/portable/IAR/RXv2/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -110,7 +110,7 @@ typedef unsigned long UBaseType_t; * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( __get_interrupt_level() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( __get_interrupt_level() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/IAR/STR71x/ISR_Support.h b/portable/IAR/STR71x/ISR_Support.h index d63e908b9..273e95141 100644 --- a/portable/IAR/STR71x/ISR_Support.h +++ b/portable/IAR/STR71x/ISR_Support.h @@ -1,6 +1,6 @@ ; /* * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * ; * * ; * SPDX-License-Identifier: MIT * ; * diff --git a/portable/IAR/STR71x/port.c b/portable/IAR/STR71x/port.c index bed6278c8..8f0e78c0d 100644 --- a/portable/IAR/STR71x/port.c +++ b/portable/IAR/STR71x/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/STR71x/portasm.s79 b/portable/IAR/STR71x/portasm.s79 index 88acc6823..87166f691 100644 --- a/portable/IAR/STR71x/portasm.s79 +++ b/portable/IAR/STR71x/portasm.s79 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/STR71x/portmacro.h b/portable/IAR/STR71x/portmacro.h index 7f5096c9d..e05c380ab 100644 --- a/portable/IAR/STR71x/portmacro.h +++ b/portable/IAR/STR71x/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/STR75x/ISR_Support.h b/portable/IAR/STR75x/ISR_Support.h index d63e908b9..273e95141 100644 --- a/portable/IAR/STR75x/ISR_Support.h +++ b/portable/IAR/STR75x/ISR_Support.h @@ -1,6 +1,6 @@ ; /* * ; * FreeRTOS Kernel - * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * ; * * ; * SPDX-License-Identifier: MIT * ; * diff --git a/portable/IAR/STR75x/port.c b/portable/IAR/STR75x/port.c index 756ba06f3..b4ec381a5 100644 --- a/portable/IAR/STR75x/port.c +++ b/portable/IAR/STR75x/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/STR75x/portasm.s79 b/portable/IAR/STR75x/portasm.s79 index 9427da1d9..ad2aa1b5e 100644 --- a/portable/IAR/STR75x/portasm.s79 +++ b/portable/IAR/STR75x/portasm.s79 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/STR75x/portmacro.h b/portable/IAR/STR75x/portmacro.h index 8be4a1a44..1d5cdabbe 100644 --- a/portable/IAR/STR75x/portmacro.h +++ b/portable/IAR/STR75x/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/STR91x/ISR_Support.h b/portable/IAR/STR91x/ISR_Support.h index c206a495b..2e6973757 100644 --- a/portable/IAR/STR91x/ISR_Support.h +++ b/portable/IAR/STR91x/ISR_Support.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/STR91x/port.c b/portable/IAR/STR91x/port.c index 8dd208016..f706c946e 100644 --- a/portable/IAR/STR91x/port.c +++ b/portable/IAR/STR91x/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/STR91x/portasm.s79 b/portable/IAR/STR91x/portasm.s79 index 575c35fb3..9b91475c7 100644 --- a/portable/IAR/STR91x/portasm.s79 +++ b/portable/IAR/STR91x/portasm.s79 @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/STR91x/portmacro.h b/portable/IAR/STR91x/portmacro.h index 853b80139..fde5b6dcb 100644 --- a/portable/IAR/STR91x/portmacro.h +++ b/portable/IAR/STR91x/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/V850ES/ISR_Support.h b/portable/IAR/V850ES/ISR_Support.h index 3f04591f4..b99126d0f 100644 --- a/portable/IAR/V850ES/ISR_Support.h +++ b/portable/IAR/V850ES/ISR_Support.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/V850ES/port.c b/portable/IAR/V850ES/port.c index 17c17b66a..d1d9d6a7d 100644 --- a/portable/IAR/V850ES/port.c +++ b/portable/IAR/V850ES/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/IAR/V850ES/portasm.s85 b/portable/IAR/V850ES/portasm.s85 index 6f795acbd..b01753667 100644 --- a/portable/IAR/V850ES/portasm.s85 +++ b/portable/IAR/V850ES/portasm.s85 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/V850ES/portasm_Fx3.s85 b/portable/IAR/V850ES/portasm_Fx3.s85 index 412077a63..12262b3af 100644 --- a/portable/IAR/V850ES/portasm_Fx3.s85 +++ b/portable/IAR/V850ES/portasm_Fx3.s85 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/V850ES/portasm_Hx2.s85 b/portable/IAR/V850ES/portasm_Hx2.s85 index 373431f84..03c2e38ae 100644 --- a/portable/IAR/V850ES/portasm_Hx2.s85 +++ b/portable/IAR/V850ES/portasm_Hx2.s85 @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/IAR/V850ES/portmacro.h b/portable/IAR/V850ES/portmacro.h index fa9f87eff..0f066a0fc 100644 --- a/portable/IAR/V850ES/portmacro.h +++ b/portable/IAR/V850ES/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC18F/port.c b/portable/MPLAB/PIC18F/port.c index a26d97116..bb8451581 100644 --- a/portable/MPLAB/PIC18F/port.c +++ b/portable/MPLAB/PIC18F/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC18F/portmacro.h b/portable/MPLAB/PIC18F/portmacro.h index 80e83ed9e..a0bfb44b5 100644 --- a/portable/MPLAB/PIC18F/portmacro.h +++ b/portable/MPLAB/PIC18F/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC24_dsPIC/port.c b/portable/MPLAB/PIC24_dsPIC/port.c index 6f23fe8a2..f309128e5 100644 --- a/portable/MPLAB/PIC24_dsPIC/port.c +++ b/portable/MPLAB/PIC24_dsPIC/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -45,7 +45,7 @@ #define portTIMER_PRESCALE 8 #define portINITIAL_SR 0 -/* Defined for backward compatability with project created prior to +/* Defined for backward compatibility with project created prior to FreeRTOS.org V4.3.0. */ #ifndef configKERNEL_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY 1 diff --git a/portable/MPLAB/PIC24_dsPIC/portasm_PIC24.S b/portable/MPLAB/PIC24_dsPIC/portasm_PIC24.S index 0019d9b45..e2a7d6267 100644 --- a/portable/MPLAB/PIC24_dsPIC/portasm_PIC24.S +++ b/portable/MPLAB/PIC24_dsPIC/portasm_PIC24.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC24_dsPIC/portasm_dsPIC.S b/portable/MPLAB/PIC24_dsPIC/portasm_dsPIC.S index ea46426f4..ec1f070a4 100644 --- a/portable/MPLAB/PIC24_dsPIC/portasm_dsPIC.S +++ b/portable/MPLAB/PIC24_dsPIC/portasm_dsPIC.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC24_dsPIC/portmacro.h b/portable/MPLAB/PIC24_dsPIC/portmacro.h index f01ee9c9b..fbac471d5 100644 --- a/portable/MPLAB/PIC24_dsPIC/portmacro.h +++ b/portable/MPLAB/PIC24_dsPIC/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MEC14xx/ISR_Support.h b/portable/MPLAB/PIC32MEC14xx/ISR_Support.h index d2fa5bb4d..ce7c4ad63 100644 --- a/portable/MPLAB/PIC32MEC14xx/ISR_Support.h +++ b/portable/MPLAB/PIC32MEC14xx/ISR_Support.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MEC14xx/port.c b/portable/MPLAB/PIC32MEC14xx/port.c index ebe9bdb7c..1f0d9cc03 100644 --- a/portable/MPLAB/PIC32MEC14xx/port.c +++ b/portable/MPLAB/PIC32MEC14xx/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MEC14xx/port_asm.S b/portable/MPLAB/PIC32MEC14xx/port_asm.S index cb5aff269..b2c37f2db 100644 --- a/portable/MPLAB/PIC32MEC14xx/port_asm.S +++ b/portable/MPLAB/PIC32MEC14xx/port_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MEC14xx/portmacro.h b/portable/MPLAB/PIC32MEC14xx/portmacro.h index d4d4f50dc..f431ae324 100644 --- a/portable/MPLAB/PIC32MEC14xx/portmacro.h +++ b/portable/MPLAB/PIC32MEC14xx/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -148,7 +148,7 @@ value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API functions are those that end in FromISR. FreeRTOS maintains a separate interrupt API to ensure API function and interrupt entry is as fast and as simple as possible. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portDISABLE_INTERRUPTS() \ { \ uint32_t ulStatus; \ diff --git a/portable/MPLAB/PIC32MX/ISR_Support.h b/portable/MPLAB/PIC32MX/ISR_Support.h index d594c7cc7..0bff08fe1 100644 --- a/portable/MPLAB/PIC32MX/ISR_Support.h +++ b/portable/MPLAB/PIC32MX/ISR_Support.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MX/port.c b/portable/MPLAB/PIC32MX/port.c index 9f9140763..582a600a3 100644 --- a/portable/MPLAB/PIC32MX/port.c +++ b/portable/MPLAB/PIC32MX/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MX/port_asm.S b/portable/MPLAB/PIC32MX/port_asm.S index bc1448dee..4e00324eb 100644 --- a/portable/MPLAB/PIC32MX/port_asm.S +++ b/portable/MPLAB/PIC32MX/port_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MX/portmacro.h b/portable/MPLAB/PIC32MX/portmacro.h index b481165e6..7868dcb8c 100644 --- a/portable/MPLAB/PIC32MX/portmacro.h +++ b/portable/MPLAB/PIC32MX/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -95,7 +95,7 @@ value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API functions are those that end in FromISR. FreeRTOS maintains a separate interrupt API to ensure API function and interrupt entry is as fast and as simple as possible. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portDISABLE_INTERRUPTS() \ { \ uint32_t ulStatus; \ diff --git a/portable/MPLAB/PIC32MZ/ISR_Support.h b/portable/MPLAB/PIC32MZ/ISR_Support.h index a9ddee0f4..292877f42 100644 --- a/portable/MPLAB/PIC32MZ/ISR_Support.h +++ b/portable/MPLAB/PIC32MZ/ISR_Support.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MZ/port.c b/portable/MPLAB/PIC32MZ/port.c index b8b5708fe..4af1fb832 100644 --- a/portable/MPLAB/PIC32MZ/port.c +++ b/portable/MPLAB/PIC32MZ/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -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/MPLAB/PIC32MZ/port_asm.S b/portable/MPLAB/PIC32MZ/port_asm.S index 4e7f639c4..78cb14165 100644 --- a/portable/MPLAB/PIC32MZ/port_asm.S +++ b/portable/MPLAB/PIC32MZ/port_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/MPLAB/PIC32MZ/portmacro.h b/portable/MPLAB/PIC32MZ/portmacro.h index e6a3f5508..8b0497086 100644 --- a/portable/MPLAB/PIC32MZ/portmacro.h +++ b/portable/MPLAB/PIC32MZ/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -97,7 +97,7 @@ value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API functions are those that end in FromISR. FreeRTOS maintains a separate interrupt API to ensure API function and interrupt entry is as fast and as simple as possible. */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portDISABLE_INTERRUPTS() \ { \ uint32_t ulStatus; \ diff --git a/portable/MSVC-MingW/port.c b/portable/MSVC-MingW/port.c index 0a0fba6a3..540c4a4bc 100644 --- a/portable/MSVC-MingW/port.c +++ b/portable/MSVC-MingW/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -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 @@ -141,6 +149,10 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter ) { TickType_t xMinimumWindowsBlockTime; TIMECAPS xTimeCaps; + 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 ) @@ -160,45 +172,36 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter ) /* Just to prevent compiler warnings. */ ( void ) lpParameter; + /* Tick time for the timer is adjusted with the maximum available + resolution. */ + if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime ) + { + xWaitTimeBetweenTicks = xMinimumWindowsBlockTime; + } + + /* Convert the tick time in milliseconds to nanoseconds resolution + for the Waitable Timer. */ + liDueTime.u.LowPart = xWaitTimeBetweenTicks * 1000 * 1000; + liDueTime.u.HighPart = 0; + + /* Create a synchronization Waitable Timer.*/ + hTimer = CreateWaitableTimer( NULL, FALSE, NULL ); + + configASSERT( hTimer != NULL ); + + /* Set the Waitable Timer. The timer is set to run periodically at every + xWaitTimeBetweenTicks milliseconds. */ + bSuccess = SetWaitableTimer( hTimer, &liDueTime, xWaitTimeBetweenTicks, NULL, NULL, 0 ); + configASSERT( bSuccess ); + while( xPortRunning == pdTRUE ) { /* Wait until the timer expires and we can access the simulated interrupt - * variables. *NOTE* this is not a 'real time' way of generating tick - * events as the next wake time should be relative to the previous wake - * time, not the time that Sleep() is called. It is done this way to - * prevent overruns in this very non real time simulated/emulated - * environment. */ - if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime ) - { - Sleep( xMinimumWindowsBlockTime ); - } - else - { - Sleep( portTICK_PERIOD_MS ); - } + * variables. */ - if( xPortRunning == pdTRUE ) - { - configASSERT( xPortRunning ); + WaitForSingleObject( hTimer, INFINITE ); - /* Can't proceed if in a critical section as pvInterruptEventMutex won't - * be available. */ - WaitForSingleObject( pvInterruptEventMutex, INFINITE ); - - /* The timer has expired, generate the simulated tick event. */ - ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK ); - - /* The interrupt is now pending - notify the simulated interrupt - * handler thread. Must be outside of a critical section to get here so - * the handler thread can execute immediately pvInterruptEventMutex is - * released. */ - configASSERT( ulCriticalNesting == 0UL ); - SetEvent( pvInterruptEvent ); - - /* Give back the mutex so the simulated interrupt handler unblocks - * and can access the interrupt handler variables. */ - ReleaseMutex( pvInterruptEventMutex ); - } + vPortGenerateSimulatedInterruptFromWindowsThread( portINTERRUPT_TICK ); } return 0; @@ -246,8 +249,19 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, FALSE, /* Start not signalled. */ NULL ); /* No name. */ + +#ifdef __GNUC__ + /* GCC reports the warning for the cast operation from TaskFunction_t to LPTHREAD_START_ROUTINE. */ + /* Disable this warning here by the #pragma option. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif /* Create the thread itself. */ pxThreadState->pvThread = CreateThread( NULL, xStackSize, ( LPTHREAD_START_ROUTINE ) pxCode, pvParameters, CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, NULL ); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + configASSERT( pxThreadState->pvThread ); /* See comment where TerminateThread() is called. */ SetThreadAffinityMask( pxThreadState->pvThread, 0x01 ); SetThreadPriorityBoost( pxThreadState->pvThread, TRUE ); @@ -342,12 +356,12 @@ BaseType_t xPortStartScheduler( void ) pxThreadState = ( ThreadState_t * ) *( ( size_t * ) pxCurrentTCB ); ulCriticalNesting = portNO_CRITICAL_NESTING; - /* Start the first task. */ - ResumeThread( pxThreadState->pvThread ); - /* The scheduler is now running. */ xPortRunning = pdTRUE; + /* Start the first task. */ + ResumeThread( pxThreadState->pvThread ); + /* Handle all simulated interrupts - including yield requests and * simulated ticks. */ prvProcessSimulatedInterrupts(); @@ -445,48 +459,31 @@ static void prvProcessSimulatedInterrupts( void ) if( ulSwitchRequired != pdFALSE ) { - void * pvOldCurrentTCB; + /* Suspend the old thread. */ + pxThreadState = ( ThreadState_t * ) *( ( size_t * ) pxCurrentTCB ); + SuspendThread( pxThreadState->pvThread ); - pvOldCurrentTCB = pxCurrentTCB; + /* Ensure the thread is actually suspended by performing a + * synchronous operation that can only complete when the thread + * is actually suspended. The below code asks for dummy register + * data. Experimentation shows that these two lines don't appear + * to do anything now, but according to + * https://devblogs.microsoft.com/oldnewthing/20150205-00/?p=44743 + * they do - so as they do not harm (slight run-time hit). */ + xContext.ContextFlags = CONTEXT_INTEGER; + ( void ) GetThreadContext( pxThreadState->pvThread, &xContext ); /* Select the next task to run. */ vTaskSwitchContext(); - /* If the task selected to enter the running state is not the task - * that is already in the running state. */ - if( pvOldCurrentTCB != pxCurrentTCB ) - { - /* Suspend the old thread. In the cases where the (simulated) - * interrupt is asynchronous (tick event swapping a task out rather - * than a task blocking or yielding) it doesn't matter if the - * 'suspend' operation doesn't take effect immediately - if it - * doesn't it would just be like the interrupt occurring slightly - * later. In cases where the yield was caused by a task blocking - * or yielding then the task will block on a yield event after the - * yield operation in case the 'suspend' operation doesn't take - * effect immediately. */ - pxThreadState = ( ThreadState_t * ) *( ( size_t * ) pvOldCurrentTCB ); - SuspendThread( pxThreadState->pvThread ); + /* Obtain the state of the task now selected to enter the + * Running state. */ + pxThreadState = ( ThreadState_t * ) ( *( size_t * ) pxCurrentTCB ); - /* Ensure the thread is actually suspended by performing a - * synchronous operation that can only complete when the thread is - * actually suspended. The below code asks for dummy register - * data. Experimentation shows that these two lines don't appear - * to do anything now, but according to - * https://devblogs.microsoft.com/oldnewthing/20150205-00/?p=44743 - * they do - so as they do not harm (slight run-time hit). */ - xContext.ContextFlags = CONTEXT_INTEGER; - ( void ) GetThreadContext( pxThreadState->pvThread, &xContext ); - - /* Obtain the state of the task now selected to enter the - * Running state. */ - pxThreadState = ( ThreadState_t * ) ( *( size_t * ) pxCurrentTCB ); - - /* pxThreadState->pvThread can be NULL if the task deleted - * itself - but a deleted task should never be resumed here. */ - configASSERT( pxThreadState->pvThread != NULL ); - ResumeThread( pxThreadState->pvThread ); - } + /* pxThreadState->pvThread can be NULL if the task deleted + * itself - but a deleted task should never be resumed here. */ + configASSERT( pxThreadState->pvThread != NULL ); + ResumeThread( pxThreadState->pvThread ); } /* If the thread that is about to be resumed stopped running @@ -574,6 +571,20 @@ void vPortCloseRunningThread( void * pvTaskToDelete, /* This is called from a critical section, which must be exited before the * thread stops. */ taskEXIT_CRITICAL(); + + /* Record that a yield is pending so that the next tick interrupt switches + * out this thread regardless of the value of configUSE_PREEMPTION. This is + * needed when a task deletes itself - the taskYIELD_WITHIN_API within + * vTaskDelete does not get called because this function never returns. If + * we do not pend portINTERRUPT_YIELD here, the next task is not scheduled + * when configUSE_PREEMPTION is set to 0. */ + if( pvInterruptEventMutex != NULL ) + { + WaitForSingleObject( pvInterruptEventMutex, INFINITE ); + ulPendingInterrupts |= ( 1 << portINTERRUPT_YIELD ); + ReleaseMutex( pvInterruptEventMutex ); + } + CloseHandle( pxThreadState->pvYieldEvent ); ExitThread( 0 ); } @@ -625,6 +636,32 @@ void vPortGenerateSimulatedInterrupt( uint32_t ulInterruptNumber ) } /*-----------------------------------------------------------*/ +void vPortGenerateSimulatedInterruptFromWindowsThread( uint32_t ulInterruptNumber ) +{ + if( xPortRunning == pdTRUE ) + { + /* Can't proceed if in a critical section as pvInterruptEventMutex won't + * be available. */ + WaitForSingleObject( pvInterruptEventMutex, INFINITE ); + + /* Pending a user defined interrupt to be handled in simulated interrupt + * handler thread. */ + ulPendingInterrupts |= ( 1 << ulInterruptNumber ); + + /* The interrupt is now pending - notify the simulated interrupt + * handler thread. Must be outside of a critical section to get here so + * the handler thread can execute immediately pvInterruptEventMutex is + * released. */ + configASSERT( ulCriticalNesting == 0UL ); + SetEvent( pvInterruptEvent ); + + /* Give back the mutex so the simulated interrupt handler unblocks + * and can access the interrupt handler variables. */ + ReleaseMutex( pvInterruptEventMutex ); + } +} +/*-----------------------------------------------------------*/ + void vPortSetInterruptHandler( uint32_t ulInterruptNumber, uint32_t ( * pvHandler )( void ) ) { diff --git a/portable/MSVC-MingW/portmacro.h b/portable/MSVC-MingW/portmacro.h index 48a8bf4b0..37bfb2586 100644 --- a/portable/MSVC-MingW/portmacro.h +++ b/portable/MSVC-MingW/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -29,17 +29,10 @@ #ifndef PORTMACRO_H #define PORTMACRO_H -#ifdef WIN32_LEAN_AND_MEAN - #include -#else - #include +#ifdef __cplusplus +extern "C" { #endif -#include -#include -#include -#include - /****************************************************************************** * Defines ******************************************************************************/ @@ -72,9 +65,18 @@ typedef portSTACK_TYPE StackType_t; typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffffffffUL -/* 32/64-bit tick type on a 32/64-bit architecture, so reads of the tick +/* 32-bit tick type on a 32/64-bit architecture, so reads of the tick * count do not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + typedef uint64_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffULL + +#if defined( __x86_64__ ) || defined( _M_X64 ) +/* 64-bit tick type on a 64-bit architecture, so reads of the tick + * count do not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif @@ -99,7 +101,7 @@ extern volatile BaseType_t xInsideInterrupt; /* Simulated interrupts return pdFALSE if no context switch should be performed, * or a non-zero number if a context switch should be performed. */ -#define portYIELD_FROM_ISR( x ) ( void ) x +#define portYIELD_FROM_ISR( x ) return x #define portEND_SWITCHING_ISR( x ) portYIELD_FROM_ISR( ( x ) ) void vPortCloseRunningThread( void * pvTaskToDelete, @@ -121,32 +123,53 @@ void vPortExitCritical( void ); #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #endif +/*-----------------------------------------------------------*/ + #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 -/* Check the configuration. */ + /* Check the configuration. */ #if ( configMAX_PRIORITIES > 32 ) #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. #endif -/* Store/clear the ready priorities in a bit map. */ - #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) - #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) - - -/*-----------------------------------------------------------*/ + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( ( ( UBaseType_t ) 1 ) << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( ( ( UBaseType_t ) 1 ) << ( uxPriority ) ) #ifdef __GNUC__ - #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \ - __asm volatile ( "bsr %1, %0\n\t" \ - : "=r" ( uxTopPriority ) : "rm" ( uxReadyPriorities ) : "cc" ) - #else -/* BitScanReverse returns the bit position of the most significant '1' - * in the word. */ - #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) _BitScanReverse( ( DWORD * ) &( uxTopPriority ), ( uxReadyPriorities ) ) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \ + __asm volatile ( "bsr %1, %0\n\t" \ + : "=r" ( uxTopPriority ) \ + : "rm" ( uxReadyPriorities ) \ + : "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 \ + { \ + 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( ( unsigned long * ) &( uxTopPriority ), ( uxReadyPriorities ) ) + + #endif /* #if defined( __x86_64__ ) || defined( _M_X64 ) */ + #endif /* __GNUC__ */ -#endif /* taskRECORD_READY_PRIORITY */ +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifndef __GNUC__ __pragma( warning( disable:4211 ) ) /* Nonstandard extension used, as extern is only nonstandard to MSVC. */ @@ -157,8 +180,9 @@ void vPortExitCritical( void ); #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) -#define portINTERRUPT_YIELD ( 0UL ) -#define portINTERRUPT_TICK ( 1UL ) +#define portINTERRUPT_YIELD ( 0UL ) +#define portINTERRUPT_TICK ( 1UL ) +#define portINTERRUPT_APPLICATION_DEFINED_START ( 2UL ) /* * Raise a simulated interrupt represented by the bit mask in ulInterruptMask. @@ -167,6 +191,14 @@ void vPortExitCritical( void ); */ void vPortGenerateSimulatedInterrupt( uint32_t ulInterruptNumber ); +/* + * Raise a simulated interrupt represented by the bit mask in ulInterruptMask. + * Each bit can be used to represent an individual interrupt - with the first + * two bits being used for the Yield and Tick interrupts respectively. This function + * can be called in a windows thread. + */ +void vPortGenerateSimulatedInterruptFromWindowsThread( uint32_t ulInterruptNumber ); + /* * Install an interrupt handler to be called by the simulated interrupt handler * thread. The interrupt number must be above any used by the kernel itself @@ -179,4 +211,8 @@ void vPortGenerateSimulatedInterrupt( uint32_t ulInterruptNumber ); void vPortSetInterruptHandler( uint32_t ulInterruptNumber, uint32_t ( * pvHandler )( void ) ); +#ifdef __cplusplus +} +#endif + #endif /* ifndef PORTMACRO_H */ diff --git a/portable/MemMang/heap_1.c b/portable/MemMang/heap_1.c index 19f695b20..f697c907c 100644 --- a/portable/MemMang/heap_1.c +++ b/portable/MemMang/heap_1.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -51,20 +51,28 @@ #endif /* A few bytes might be lost to byte aligning the heap start address. */ -#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* Max value that fits in a size_t type. */ +#define heapSIZE_MAX ( ~( ( size_t ) 0 ) ) + +/* Check if adding a and b will result in overflow. */ +#define heapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( heapSIZE_MAX - ( b ) ) ) + +/*-----------------------------------------------------------*/ /* Allocate the memory for the heap. */ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS -* heap - probably so it can be placed in a special segment or address. */ + * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ /* Index into the ucHeap array. */ -static size_t xNextFreeByte = ( size_t ) 0; +static size_t xNextFreeByte = ( size_t ) 0U; /*-----------------------------------------------------------*/ @@ -76,12 +84,16 @@ void * pvPortMalloc( size_t xWantedSize ) /* Ensure that blocks are always aligned. */ #if ( portBYTE_ALIGNMENT != 1 ) { - if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + size_t xAdditionalRequiredSize; + + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) { - /* Byte alignment required. Check for overflow. */ - if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) ) > xWantedSize ) + /* Byte alignment required. */ + xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); + + if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) { - xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + xWantedSize += xAdditionalRequiredSize; } else { @@ -96,13 +108,14 @@ void * pvPortMalloc( size_t xWantedSize ) if( pucAlignedHeap == NULL ) { /* Ensure the heap starts on a correctly aligned boundary. */ - pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT - 1 ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &( ucHeap[ portBYTE_ALIGNMENT - 1 ] ) ) & + ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); } - /* Check there is enough room left for the allocation and. */ - if( ( xWantedSize > 0 ) && /* valid size */ - ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && - ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) ) /* Check for overflow. */ + /* Check there is enough room left for the allocation. */ + if( ( xWantedSize > 0 ) && + ( heapADD_WILL_OVERFLOW( xNextFreeByte, xWantedSize ) == 0 ) && + ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) ) { /* Return the next free byte then increment the index past this * block. */ @@ -150,3 +163,16 @@ size_t xPortGetFreeHeapSize( void ) { return( configADJUSTED_HEAP_SIZE - xNextFreeByte ); } + +/*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + xNextFreeByte = ( size_t ) 0U; +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_2.c b/portable/MemMang/heap_2.c index fffcb9ca3..fa6ea9d9b 100644 --- a/portable/MemMang/heap_2.c +++ b/portable/MemMang/heap_2.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -87,7 +87,7 @@ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS -* heap - probably so it can be placed in a special segment or address. */ + * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; @@ -113,6 +113,9 @@ PRIVILEGED_DATA static BlockLink_t xStart, xEnd; * fragmentation. */ PRIVILEGED_DATA static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; +/* Indicates whether the heap has been initialised or not. */ +PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE; + /*-----------------------------------------------------------*/ /* @@ -155,9 +158,9 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; - PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; if( xWantedSize > 0 ) { @@ -259,6 +262,8 @@ void * pvPortMalloc( size_t xWantedSize ) xFreeBytesRemaining -= pxBlock->xBlockSize; + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned * by the application and has no "next" block. */ heapALLOCATE_BLOCK( pxBlock ); @@ -267,7 +272,10 @@ void * pvPortMalloc( size_t xWantedSize ) } } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; } ( void ) xTaskResumeAll(); @@ -384,3 +392,16 @@ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ pxFirstFreeBlock->pxNextFreeBlock = &xEnd; } /*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + + xHeapHasBeenInitialised = pdFALSE; +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_3.c b/portable/MemMang/heap_3.c index d174a57e9..5094390b5 100644 --- a/portable/MemMang/heap_3.c +++ b/portable/MemMang/heap_3.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -92,3 +92,15 @@ void vPortFree( void * pv ) ( void ) xTaskResumeAll(); } } +/*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + /* No state needs to be re-initialised in heap_3. */ +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_4.c b/portable/MemMang/heap_4.c index 507bf48b9..50af15dfb 100644 --- a/portable/MemMang/heap_4.c +++ b/portable/MemMang/heap_4.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -89,7 +89,7 @@ #if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS -* heap - probably so it can be placed in a special segment or address. */ + * heap - probably so it can be placed in a special segment or address. */ extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; @@ -163,10 +163,10 @@ PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL; /* Keeps track of the number of calls to allocate and free memory as well as the * number of free bytes remaining, but says nothing about fragmentation. */ -PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; +PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U; /*-----------------------------------------------------------*/ @@ -177,6 +177,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; if( xWantedSize > 0 ) { @@ -302,10 +303,12 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned * by the application and has no "next" block. */ heapALLOCATE_BLOCK( pxBlock ); - pxBlock->pxNextFreeBlock = NULL; + pxBlock->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( NULL ); xNumberOfSuccessfulAllocations++; } else @@ -323,7 +326,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; } ( void ) xTaskResumeAll(); @@ -361,11 +367,11 @@ void vPortFree( void * pv ) heapVALIDATE_BLOCK_POINTER( pxLink ); configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ); - configASSERT( pxLink->pxNextFreeBlock == NULL ); + configASSERT( pxLink->pxNextFreeBlock == heapPROTECT_BLOCK_POINTER( NULL ) ); if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ) { - if( pxLink->pxNextFreeBlock == NULL ) + if( pxLink->pxNextFreeBlock == heapPROTECT_BLOCK_POINTER( NULL ) ) { /* The block is being returned to the heap - it is no longer * allocated. */ @@ -416,6 +422,12 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) } /*-----------------------------------------------------------*/ +void xPortResetHeapMinimumEverFreeHeapSize( void ) +{ + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + void vPortInitialiseBlocks( void ) { /* This just exists to keep the linker quiet. */ @@ -542,7 +554,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVI pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; } - /* If the block being inserted plugged a gab, so was merged with the block + /* If the block being inserted plugged a gap, so was merged with the block * before and the block after, then it's pxNextFreeBlock pointer will have * already been set, and should not be set here as that would make it point * to itself. */ @@ -560,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(); { @@ -608,3 +620,19 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + pxEnd = NULL; + + xFreeBytesRemaining = ( size_t ) 0U; + xMinimumEverFreeBytesRemaining = ( size_t ) 0U; + xNumberOfSuccessfulAllocations = ( size_t ) 0U; + xNumberOfSuccessfulFrees = ( size_t ) 0U; +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_5.c b/portable/MemMang/heap_5.c index 18234626a..bf321304f 100644 --- a/portable/MemMang/heap_5.c +++ b/portable/MemMang/heap_5.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -129,12 +129,19 @@ * heapVALIDATE_BLOCK_POINTER assert. */ #define heapPROTECT_BLOCK_POINTER( pxBlock ) ( ( BlockLink_t * ) ( ( ( portPOINTER_SIZE_TYPE ) ( pxBlock ) ) ^ xHeapCanary ) ) -/* Assert that a heap block pointer is within the heap bounds. */ - #define heapVALIDATE_BLOCK_POINTER( pxBlock ) \ - configASSERT( ( pucHeapHighAddress != NULL ) && \ - ( pucHeapLowAddress != NULL ) && \ - ( ( uint8_t * ) ( pxBlock ) >= pucHeapLowAddress ) && \ - ( ( uint8_t * ) ( pxBlock ) < pucHeapHighAddress ) ) +/* Assert that a heap block pointer is within the heap bounds. + * Setting configVALIDATE_HEAP_BLOCK_POINTER to 1 enables customized heap block pointers + * protection on heap_5. */ + #ifndef configVALIDATE_HEAP_BLOCK_POINTER + #define heapVALIDATE_BLOCK_POINTER( pxBlock ) \ + configASSERT( ( pucHeapHighAddress != NULL ) && \ + ( pucHeapLowAddress != NULL ) && \ + ( ( uint8_t * ) ( pxBlock ) >= pucHeapLowAddress ) && \ + ( ( uint8_t * ) ( pxBlock ) < pucHeapHighAddress ) ) + #else /* ifndef configVALIDATE_HEAP_BLOCK_POINTER */ + #define heapVALIDATE_BLOCK_POINTER( pxBlock ) \ + configVALIDATE_HEAP_BLOCK_POINTER( pxBlock ) + #endif /* configVALIDATE_HEAP_BLOCK_POINTER */ #else /* if ( configENABLE_HEAP_PROTECTOR == 1 ) */ @@ -187,10 +194,10 @@ PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL; /* Keeps track of the number of calls to allocate and free memory as well as the * number of free bytes remaining, but says nothing about fragmentation. */ -PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; +PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U; #if ( configENABLE_HEAP_PROTECTOR == 1 ) @@ -212,6 +219,7 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxNewBlockLink; void * pvReturn = NULL; size_t xAdditionalRequiredSize; + size_t xAllocatedBlockSize = 0; /* The heap must be initialised before the first call to * pvPortMalloc(). */ @@ -330,10 +338,12 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } + xAllocatedBlockSize = pxBlock->xBlockSize; + /* The block is being returned - it is allocated and owned * by the application and has no "next" block. */ heapALLOCATE_BLOCK( pxBlock ); - pxBlock->pxNextFreeBlock = NULL; + pxBlock->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( NULL ); xNumberOfSuccessfulAllocations++; } else @@ -351,7 +361,10 @@ void * pvPortMalloc( size_t xWantedSize ) mtCOVERAGE_TEST_MARKER(); } - traceMALLOC( pvReturn, xWantedSize ); + traceMALLOC( pvReturn, xAllocatedBlockSize ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xAllocatedBlockSize; } ( void ) xTaskResumeAll(); @@ -389,11 +402,11 @@ void vPortFree( void * pv ) heapVALIDATE_BLOCK_POINTER( pxLink ); configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ); - configASSERT( pxLink->pxNextFreeBlock == NULL ); + configASSERT( pxLink->pxNextFreeBlock == heapPROTECT_BLOCK_POINTER( NULL ) ); if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ) { - if( pxLink->pxNextFreeBlock == NULL ) + if( pxLink->pxNextFreeBlock == heapPROTECT_BLOCK_POINTER( NULL ) ) { /* The block is being returned to the heap - it is no longer * allocated. */ @@ -444,6 +457,12 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) } /*-----------------------------------------------------------*/ +void xPortResetHeapMinimumEverFreeHeapSize( void ) +{ + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + void * pvPortCalloc( size_t xNum, size_t xSize ) { @@ -653,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(); { @@ -707,3 +726,24 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + pxEnd = NULL; + + xFreeBytesRemaining = ( size_t ) 0U; + xMinimumEverFreeBytesRemaining = ( size_t ) 0U; + xNumberOfSuccessfulAllocations = ( size_t ) 0U; + xNumberOfSuccessfulFrees = ( size_t ) 0U; + + #if ( configENABLE_HEAP_PROTECTOR == 1 ) + pucHeapHighAddress = NULL; + pucHeapLowAddress = NULL; + #endif /* #if ( configENABLE_HEAP_PROTECTOR == 1 ) */ +} +/*-----------------------------------------------------------*/ diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c index eeeb6b70b..a167f8588 100644 --- a/portable/MikroC/ARM_CM4F/port.c +++ b/portable/MikroC/ARM_CM4F/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -892,7 +892,7 @@ BaseType_t xPortIsInsideInterrupt( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/MikroC/ARM_CM4F/portmacro.h b/portable/MikroC/ARM_CM4F/portmacro.h index 3d00da05a..d6cd752e4 100644 --- a/portable/MikroC/ARM_CM4F/portmacro.h +++ b/portable/MikroC/ARM_CM4F/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -175,7 +175,7 @@ /*-----------------------------------------------------------*/ - #ifdef configASSERT + #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/Paradigm/Tern_EE/large_untested/port.c b/portable/Paradigm/Tern_EE/large_untested/port.c index 4ecffe01a..443104885 100644 --- a/portable/Paradigm/Tern_EE/large_untested/port.c +++ b/portable/Paradigm/Tern_EE/large_untested/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Paradigm/Tern_EE/large_untested/portasm.h b/portable/Paradigm/Tern_EE/large_untested/portasm.h index c3c7456a3..cf9e711c8 100644 --- a/portable/Paradigm/Tern_EE/large_untested/portasm.h +++ b/portable/Paradigm/Tern_EE/large_untested/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Paradigm/Tern_EE/large_untested/portmacro.h b/portable/Paradigm/Tern_EE/large_untested/portmacro.h index 292c9e260..1ea0c3176 100644 --- a/portable/Paradigm/Tern_EE/large_untested/portmacro.h +++ b/portable/Paradigm/Tern_EE/large_untested/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Paradigm/Tern_EE/small/port.c b/portable/Paradigm/Tern_EE/small/port.c index 2a1c0d962..75273f225 100644 --- a/portable/Paradigm/Tern_EE/small/port.c +++ b/portable/Paradigm/Tern_EE/small/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Paradigm/Tern_EE/small/portasm.h b/portable/Paradigm/Tern_EE/small/portasm.h index 930da20b0..88ef3ba99 100644 --- a/portable/Paradigm/Tern_EE/small/portasm.h +++ b/portable/Paradigm/Tern_EE/small/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Paradigm/Tern_EE/small/portmacro.h b/portable/Paradigm/Tern_EE/small/portmacro.h index ff0b34b20..0ab083838 100644 --- a/portable/Paradigm/Tern_EE/small/portmacro.h +++ b/portable/Paradigm/Tern_EE/small/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/RVDS/ARM7_LPC21xx/port.c b/portable/RVDS/ARM7_LPC21xx/port.c index 2d890e19d..5476af8c9 100644 --- a/portable/RVDS/ARM7_LPC21xx/port.c +++ b/portable/RVDS/ARM7_LPC21xx/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/RVDS/ARM7_LPC21xx/portASM.s b/portable/RVDS/ARM7_LPC21xx/portASM.s index 4398ca128..c47a9a641 100644 --- a/portable/RVDS/ARM7_LPC21xx/portASM.s +++ b/portable/RVDS/ARM7_LPC21xx/portASM.s @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/RVDS/ARM7_LPC21xx/portmacro.h b/portable/RVDS/ARM7_LPC21xx/portmacro.h index be0628b77..5535dcfef 100644 --- a/portable/RVDS/ARM7_LPC21xx/portmacro.h +++ b/portable/RVDS/ARM7_LPC21xx/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/RVDS/ARM7_LPC21xx/portmacro.inc b/portable/RVDS/ARM7_LPC21xx/portmacro.inc index 62b1a8731..ef84d1adf 100644 --- a/portable/RVDS/ARM7_LPC21xx/portmacro.inc +++ b/portable/RVDS/ARM7_LPC21xx/portmacro.inc @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/RVDS/ARM_CA9/port.c b/portable/RVDS/ARM_CA9/port.c index d3870b8ed..7ef38f399 100644 --- a/portable/RVDS/ARM_CA9/port.c +++ b/portable/RVDS/ARM_CA9/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -465,7 +465,7 @@ uint32_t ulPortSetInterruptMask( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); /* Priority grouping: The interrupt controller (GIC) allows the bits @@ -476,7 +476,7 @@ uint32_t ulPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( portICCBPR_BINARY_POINT_REGISTER <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/RVDS/ARM_CA9/portASM.s b/portable/RVDS/ARM_CA9/portASM.s index a5ac2fc0b..771b140da 100644 --- a/portable/RVDS/ARM_CA9/portASM.s +++ b/portable/RVDS/ARM_CA9/portASM.s @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * @@ -143,7 +143,7 @@ exit_without_switch MOVS PC, LR switch_before_exit - ; A context swtich is to be performed. Clear the context switch pending + ; A context switch is to be performed. Clear the context switch pending ; flag. MOV r0, #0 STR r0, [r1] diff --git a/portable/RVDS/ARM_CA9/portmacro.h b/portable/RVDS/ARM_CA9/portmacro.h index fbe3472da..2218a6379 100644 --- a/portable/RVDS/ARM_CA9/portmacro.h +++ b/portable/RVDS/ARM_CA9/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -153,7 +153,7 @@ void vPortTaskUsesFPU( void ); #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/RVDS/ARM_CA9/portmacro.inc b/portable/RVDS/ARM_CA9/portmacro.inc index 93b8d8db6..68a73945f 100644 --- a/portable/RVDS/ARM_CA9/portmacro.inc +++ b/portable/RVDS/ARM_CA9/portmacro.inc @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/RVDS/ARM_CM0/port.c b/portable/RVDS/ARM_CM0/port.c index 96947d215..ececb715a 100644 --- a/portable/RVDS/ARM_CM0/port.c +++ b/portable/RVDS/ARM_CM0/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/RVDS/ARM_CM0/portmacro.h b/portable/RVDS/ARM_CM0/portmacro.h index 1b5821a71..785138722 100644 --- a/portable/RVDS/ARM_CM0/portmacro.h +++ b/portable/RVDS/ARM_CM0/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c index 9a6af5acc..725127193 100644 --- a/portable/RVDS/ARM_CM3/port.c +++ b/portable/RVDS/ARM_CM3/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -770,7 +770,7 @@ __asm uint32_t vPortGetIPSR( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/RVDS/ARM_CM3/portmacro.h b/portable/RVDS/ARM_CM3/portmacro.h index 4b8fbdb99..0436525fd 100644 --- a/portable/RVDS/ARM_CM3/portmacro.h +++ b/portable/RVDS/ARM_CM3/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -165,7 +165,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c index c6d825b82..8d21daffb 100644 --- a/portable/RVDS/ARM_CM4F/port.c +++ b/portable/RVDS/ARM_CM4F/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -866,7 +866,7 @@ __asm uint32_t vPortGetIPSR( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/RVDS/ARM_CM4F/portmacro.h b/portable/RVDS/ARM_CM4F/portmacro.h index 03ea9e95a..063b148f4 100644 --- a/portable/RVDS/ARM_CM4F/portmacro.h +++ b/portable/RVDS/ARM_CM4F/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -165,7 +165,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c b/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c index d65876356..950788e09 100644 --- a/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c +++ b/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -60,12 +60,11 @@ __asm BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskDelayUntil_Unpriv MPU_xTaskDelayUntil_Priv - pop {r0} b MPU_xTaskDelayUntilImpl MPU_xTaskDelayUntil_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskDelayUntil } @@ -84,12 +83,11 @@ __asm BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CA push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskAbortDelay_Unpriv MPU_xTaskAbortDelay_Priv - pop {r0} b MPU_xTaskAbortDelayImpl MPU_xTaskAbortDelay_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskAbortDelay } @@ -108,12 +106,11 @@ __asm void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* FREERTOS_SYSTEM_C push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskDelay_Unpriv MPU_vTaskDelay_Priv - pop {r0} b MPU_vTaskDelayImpl MPU_vTaskDelay_Unpriv - pop {r0} svc #SYSTEM_CALL_vTaskDelay } @@ -132,12 +129,11 @@ __asm UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* FREERTOS_ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskPriorityGet_Unpriv MPU_uxTaskPriorityGet_Priv - pop {r0} b MPU_uxTaskPriorityGetImpl MPU_uxTaskPriorityGet_Unpriv - pop {r0} svc #SYSTEM_CALL_uxTaskPriorityGet } @@ -156,12 +152,11 @@ __asm eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_eTaskGetState_Unpriv MPU_eTaskGetState_Priv - pop {r0} b MPU_eTaskGetStateImpl MPU_eTaskGetState_Unpriv - pop {r0} svc #SYSTEM_CALL_eTaskGetState } @@ -186,12 +181,11 @@ __asm void MPU_vTaskGetInfo( TaskHandle_t xTask, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskGetInfo_Unpriv MPU_vTaskGetInfo_Priv - pop {r0} b MPU_vTaskGetInfoImpl MPU_vTaskGetInfo_Unpriv - pop {r0} svc #SYSTEM_CALL_vTaskGetInfo } @@ -210,12 +204,11 @@ __asm TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetIdleTaskHandle_Unpriv MPU_xTaskGetIdleTaskHandle_Priv - pop {r0} b MPU_xTaskGetIdleTaskHandleImpl MPU_xTaskGetIdleTaskHandle_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGetIdleTaskHandle } @@ -234,12 +227,11 @@ __asm void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* FREERTOS_SYSTEM_CA push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSuspend_Unpriv MPU_vTaskSuspend_Priv - pop {r0} b MPU_vTaskSuspendImpl MPU_vTaskSuspend_Unpriv - pop {r0} svc #SYSTEM_CALL_vTaskSuspend } @@ -258,12 +250,11 @@ __asm void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* FREERTOS_SYSTEM_CALL push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskResume_Unpriv MPU_vTaskResume_Priv - pop {r0} b MPU_vTaskResumeImpl MPU_vTaskResume_Unpriv - pop {r0} svc #SYSTEM_CALL_vTaskResume } @@ -280,12 +271,11 @@ __asm TickType_t MPU_xTaskGetTickCount( void ) /* FREERTOS_SYSTEM_CALL */ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetTickCount_Unpriv MPU_xTaskGetTickCount_Priv - pop {r0} b MPU_xTaskGetTickCountImpl MPU_xTaskGetTickCount_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGetTickCount } /*-----------------------------------------------------------*/ @@ -300,12 +290,11 @@ __asm UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* FREERTOS_SYSTEM_CALL */ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetNumberOfTasks_Unpriv MPU_uxTaskGetNumberOfTasks_Priv - pop {r0} b MPU_uxTaskGetNumberOfTasksImpl MPU_uxTaskGetNumberOfTasks_Unpriv - pop {r0} svc #SYSTEM_CALL_uxTaskGetNumberOfTasks } /*-----------------------------------------------------------*/ @@ -322,12 +311,11 @@ __asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimeCounter_Unpriv MPU_ulTaskGetRunTimeCounter_Priv - pop {r0} b MPU_ulTaskGetRunTimeCounterImpl MPU_ulTaskGetRunTimeCounter_Unpriv - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimeCounter } @@ -346,12 +334,11 @@ __asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetRunTimePercent_Unpriv MPU_ulTaskGetRunTimePercent_Priv - pop {r0} b MPU_ulTaskGetRunTimePercentImpl MPU_ulTaskGetRunTimePercent_Unpriv - pop {r0} svc #SYSTEM_CALL_ulTaskGetRunTimePercent } @@ -370,12 +357,11 @@ __asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* FRE push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimePercent_Unpriv MPU_ulTaskGetIdleRunTimePercent_Priv - pop {r0} b MPU_ulTaskGetIdleRunTimePercentImpl MPU_ulTaskGetIdleRunTimePercent_Unpriv - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimePercent } @@ -394,12 +380,11 @@ __asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* FRE push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv MPU_ulTaskGetIdleRunTimeCounter_Priv - pop {r0} b MPU_ulTaskGetIdleRunTimeCounterImpl MPU_ulTaskGetIdleRunTimeCounter_Unpriv - pop {r0} svc #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter } @@ -420,12 +405,11 @@ __asm void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetApplicationTaskTag_Unpriv MPU_vTaskSetApplicationTaskTag_Priv - pop {r0} b MPU_vTaskSetApplicationTaskTagImpl MPU_vTaskSetApplicationTaskTag_Unpriv - pop {r0} svc #SYSTEM_CALL_vTaskSetApplicationTaskTag } @@ -444,12 +428,11 @@ __asm TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetApplicationTaskTag_Unpriv MPU_xTaskGetApplicationTaskTag_Priv - pop {r0} b MPU_xTaskGetApplicationTaskTagImpl MPU_xTaskGetApplicationTaskTag_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGetApplicationTaskTag } @@ -472,12 +455,11 @@ __asm void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv MPU_vTaskSetThreadLocalStoragePointer_Priv - pop {r0} b MPU_vTaskSetThreadLocalStoragePointerImpl MPU_vTaskSetThreadLocalStoragePointer_Unpriv - pop {r0} svc #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer } @@ -498,12 +480,11 @@ __asm void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv MPU_pvTaskGetThreadLocalStoragePointer_Priv - pop {r0} b MPU_pvTaskGetThreadLocalStoragePointerImpl MPU_pvTaskGetThreadLocalStoragePointer_Unpriv - pop {r0} svc #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer } @@ -526,12 +507,11 @@ __asm UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArr push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetSystemState_Unpriv MPU_uxTaskGetSystemState_Priv - pop {r0} b MPU_uxTaskGetSystemStateImpl MPU_uxTaskGetSystemState_Unpriv - pop {r0} svc #SYSTEM_CALL_uxTaskGetSystemState } @@ -550,12 +530,11 @@ __asm UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* FREER push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark_Unpriv MPU_uxTaskGetStackHighWaterMark_Priv - pop {r0} b MPU_uxTaskGetStackHighWaterMarkImpl MPU_uxTaskGetStackHighWaterMark_Unpriv - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark } @@ -574,12 +553,11 @@ __asm configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTas push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTaskGetStackHighWaterMark2_Unpriv MPU_uxTaskGetStackHighWaterMark2_Priv - pop {r0} b MPU_uxTaskGetStackHighWaterMark2Impl MPU_uxTaskGetStackHighWaterMark2_Unpriv - pop {r0} svc #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 } @@ -598,12 +576,11 @@ __asm TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetCurrentTaskHandle_Unpriv MPU_xTaskGetCurrentTaskHandle_Priv - pop {r0} b MPU_xTaskGetCurrentTaskHandleImpl MPU_xTaskGetCurrentTaskHandle_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGetCurrentTaskHandle } @@ -622,12 +599,11 @@ __asm BaseType_t MPU_xTaskGetSchedulerState( void ) /* FREERTOS_SYSTEM_CALL */ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGetSchedulerState_Unpriv MPU_xTaskGetSchedulerState_Priv - pop {r0} b MPU_xTaskGetSchedulerStateImpl MPU_xTaskGetSchedulerState_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGetSchedulerState } @@ -644,12 +620,11 @@ __asm void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* FREERTOS_S push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTaskSetTimeOutState_Unpriv MPU_vTaskSetTimeOutState_Priv - pop {r0} b MPU_vTaskSetTimeOutStateImpl MPU_vTaskSetTimeOutState_Unpriv - pop {r0} svc #SYSTEM_CALL_vTaskSetTimeOutState } /*-----------------------------------------------------------*/ @@ -666,12 +641,11 @@ __asm BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskCheckForTimeOut_Unpriv MPU_xTaskCheckForTimeOut_Priv - pop {r0} b MPU_xTaskCheckForTimeOutImpl MPU_xTaskCheckForTimeOut_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskCheckForTimeOut } /*-----------------------------------------------------------*/ @@ -688,12 +662,11 @@ __asm BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotify_Unpriv MPU_xTaskGenericNotify_Priv - pop {r0} b MPU_xTaskGenericNotifyImpl MPU_xTaskGenericNotify_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotify } @@ -712,12 +685,11 @@ __asm BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitPa push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyWait_Unpriv MPU_xTaskGenericNotifyWait_Priv - pop {r0} b MPU_xTaskGenericNotifyWaitImpl MPU_xTaskGenericNotifyWait_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyWait } @@ -740,12 +712,11 @@ __asm uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyTake_Unpriv MPU_ulTaskGenericNotifyTake_Priv - pop {r0} b MPU_ulTaskGenericNotifyTakeImpl MPU_ulTaskGenericNotifyTake_Unpriv - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyTake } @@ -766,12 +737,11 @@ __asm BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTaskGenericNotifyStateClear_Unpriv MPU_xTaskGenericNotifyStateClear_Priv - pop {r0} b MPU_xTaskGenericNotifyStateClearImpl MPU_xTaskGenericNotifyStateClear_Unpriv - pop {r0} svc #SYSTEM_CALL_xTaskGenericNotifyStateClear } @@ -794,12 +764,11 @@ __asm uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_ulTaskGenericNotifyValueClear_Unpriv MPU_ulTaskGenericNotifyValueClear_Priv - pop {r0} b MPU_ulTaskGenericNotifyValueClearImpl MPU_ulTaskGenericNotifyValueClear_Unpriv - pop {r0} svc #SYSTEM_CALL_ulTaskGenericNotifyValueClear } @@ -822,12 +791,11 @@ __asm BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGenericSend_Unpriv MPU_xQueueGenericSend_Priv - pop {r0} b MPU_xQueueGenericSendImpl MPU_xQueueGenericSend_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueGenericSend } /*-----------------------------------------------------------*/ @@ -842,12 +810,11 @@ __asm UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* FR push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueMessagesWaiting_Unpriv MPU_uxQueueMessagesWaiting_Priv - pop {r0} b MPU_uxQueueMessagesWaitingImpl MPU_uxQueueMessagesWaiting_Unpriv - pop {r0} svc #SYSTEM_CALL_uxQueueMessagesWaiting } /*-----------------------------------------------------------*/ @@ -862,12 +829,11 @@ __asm UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* FR push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxQueueSpacesAvailable_Unpriv MPU_uxQueueSpacesAvailable_Priv - pop {r0} b MPU_uxQueueSpacesAvailableImpl MPU_uxQueueSpacesAvailable_Unpriv - pop {r0} svc #SYSTEM_CALL_uxQueueSpacesAvailable } /*-----------------------------------------------------------*/ @@ -886,12 +852,11 @@ __asm BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueReceive_Unpriv MPU_xQueueReceive_Priv - pop {r0} b MPU_xQueueReceiveImpl MPU_xQueueReceive_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueReceive } /*-----------------------------------------------------------*/ @@ -910,12 +875,11 @@ __asm BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueuePeek_Unpriv MPU_xQueuePeek_Priv - pop {r0} b MPU_xQueuePeekImpl MPU_xQueuePeek_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueuePeek } /*-----------------------------------------------------------*/ @@ -932,12 +896,11 @@ __asm BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSemaphoreTake_Unpriv MPU_xQueueSemaphoreTake_Priv - pop {r0} b MPU_xQueueSemaphoreTakeImpl MPU_xQueueSemaphoreTake_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueSemaphoreTake } /*-----------------------------------------------------------*/ @@ -954,12 +917,11 @@ __asm TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* FREER push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGetMutexHolder_Unpriv MPU_xQueueGetMutexHolder_Priv - pop {r0} b MPU_xQueueGetMutexHolderImpl MPU_xQueueGetMutexHolder_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueGetMutexHolder } @@ -980,12 +942,11 @@ __asm BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueTakeMutexRecursive_Unpriv MPU_xQueueTakeMutexRecursive_Priv - pop {r0} b MPU_xQueueTakeMutexRecursiveImpl MPU_xQueueTakeMutexRecursive_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueTakeMutexRecursive } @@ -1004,12 +965,11 @@ __asm BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* FREERT push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueGiveMutexRecursive_Unpriv MPU_xQueueGiveMutexRecursive_Priv - pop {r0} b MPU_xQueueGiveMutexRecursiveImpl MPU_xQueueGiveMutexRecursive_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueGiveMutexRecursive } @@ -1030,12 +990,11 @@ __asm QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueSelectFromSet_Unpriv MPU_xQueueSelectFromSet_Priv - pop {r0} b MPU_xQueueSelectFromSetImpl MPU_xQueueSelectFromSet_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueSelectFromSet } @@ -1056,12 +1015,11 @@ __asm BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xQueueAddToSet_Unpriv MPU_xQueueAddToSet_Priv - pop {r0} b MPU_xQueueAddToSetImpl MPU_xQueueAddToSet_Unpriv - pop {r0} svc #SYSTEM_CALL_xQueueAddToSet } @@ -1082,12 +1040,11 @@ __asm void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueAddToRegistry_Unpriv MPU_vQueueAddToRegistry_Priv - pop {r0} b MPU_vQueueAddToRegistryImpl MPU_vQueueAddToRegistry_Unpriv - pop {r0} svc #SYSTEM_CALL_vQueueAddToRegistry } @@ -1106,12 +1063,11 @@ __asm void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vQueueUnregisterQueue_Unpriv MPU_vQueueUnregisterQueue_Priv - pop {r0} b MPU_vQueueUnregisterQueueImpl MPU_vQueueUnregisterQueue_Unpriv - pop {r0} svc #SYSTEM_CALL_vQueueUnregisterQueue } @@ -1130,12 +1086,11 @@ __asm const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcQueueGetName_Unpriv MPU_pcQueueGetName_Priv - pop {r0} b MPU_pcQueueGetNameImpl MPU_pcQueueGetName_Unpriv - pop {r0} svc #SYSTEM_CALL_pcQueueGetName } @@ -1154,12 +1109,11 @@ __asm void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* FREERTOS_SYS push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pvTimerGetTimerID_Unpriv MPU_pvTimerGetTimerID_Priv - pop {r0} b MPU_pvTimerGetTimerIDImpl MPU_pvTimerGetTimerID_Unpriv - pop {r0} svc #SYSTEM_CALL_pvTimerGetTimerID } @@ -1180,12 +1134,11 @@ __asm void MPU_vTimerSetTimerID( TimerHandle_t xTimer, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetTimerID_Unpriv MPU_vTimerSetTimerID_Priv - pop {r0} b MPU_vTimerSetTimerIDImpl MPU_vTimerSetTimerID_Unpriv - pop {r0} svc #SYSTEM_CALL_vTimerSetTimerID } @@ -1204,12 +1157,11 @@ __asm BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* FREERTOS_SYS push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerIsTimerActive_Unpriv MPU_xTimerIsTimerActive_Priv - pop {r0} b MPU_xTimerIsTimerActiveImpl MPU_xTimerIsTimerActive_Unpriv - pop {r0} svc #SYSTEM_CALL_xTimerIsTimerActive } @@ -1228,12 +1180,11 @@ __asm TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* FREERTOS_SYSTEM push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv MPU_xTimerGetTimerDaemonTaskHandle_Priv - pop {r0} b MPU_xTimerGetTimerDaemonTaskHandleImpl MPU_xTimerGetTimerDaemonTaskHandle_Unpriv - pop {r0} svc #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle } @@ -1252,12 +1203,11 @@ __asm BaseType_t MPU_xTimerGenericCommandFromTaskEntry( const xTimerGenericComma push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGenericCommandFromTask_Unpriv MPU_xTimerGenericCommandFromTask_Priv - pop {r0} b MPU_xTimerGenericCommandFromTaskImpl MPU_xTimerGenericCommandFromTask_Unpriv - pop {r0} svc #SYSTEM_CALL_xTimerGenericCommandFromTask } @@ -1276,12 +1226,11 @@ __asm const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_pcTimerGetName_Unpriv MPU_pcTimerGetName_Priv - pop {r0} b MPU_pcTimerGetNameImpl MPU_pcTimerGetName_Unpriv - pop {r0} svc #SYSTEM_CALL_pcTimerGetName } @@ -1291,10 +1240,10 @@ MPU_pcTimerGetName_Unpriv #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) FREERTOS_SYSTEM_CALL; __asm void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* FREERTOS_SYSTEM_CALL */ { PRESERVE8 extern MPU_vTimerSetReloadModeImpl @@ -1302,12 +1251,11 @@ __asm void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vTimerSetReloadMode_Unpriv MPU_vTimerSetReloadMode_Priv - pop {r0} b MPU_vTimerSetReloadModeImpl MPU_vTimerSetReloadMode_Unpriv - pop {r0} svc #SYSTEM_CALL_vTimerSetReloadMode } @@ -1326,12 +1274,11 @@ __asm BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* FREERTOS_SYS push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetReloadMode_Unpriv MPU_xTimerGetReloadMode_Priv - pop {r0} b MPU_xTimerGetReloadModeImpl MPU_xTimerGetReloadMode_Unpriv - pop {r0} svc #SYSTEM_CALL_xTimerGetReloadMode } @@ -1350,12 +1297,11 @@ __asm UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* FREERTOS_S push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxTimerGetReloadMode_Unpriv MPU_uxTimerGetReloadMode_Priv - pop {r0} b MPU_uxTimerGetReloadModeImpl MPU_uxTimerGetReloadMode_Unpriv - pop {r0} svc #SYSTEM_CALL_uxTimerGetReloadMode } @@ -1374,12 +1320,11 @@ __asm TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetPeriod_Unpriv MPU_xTimerGetPeriod_Priv - pop {r0} b MPU_xTimerGetPeriodImpl MPU_xTimerGetPeriod_Unpriv - pop {r0} svc #SYSTEM_CALL_xTimerGetPeriod } @@ -1398,18 +1343,19 @@ __asm TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* FREERTOS_SYS push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xTimerGetExpiryTime_Unpriv MPU_xTimerGetExpiryTime_Priv - pop {r0} b MPU_xTimerGetExpiryTimeImpl MPU_xTimerGetExpiryTime_Unpriv - pop {r0} svc #SYSTEM_CALL_xTimerGetExpiryTime } #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) FREERTOS_SYSTEM_CALL; __asm EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) /* FREERTOS_SYSTEM_CALL */ @@ -1420,16 +1366,19 @@ __asm EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_ push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupWaitBits_Unpriv MPU_xEventGroupWaitBits_Priv - pop {r0} b MPU_xEventGroupWaitBitsImpl MPU_xEventGroupWaitBits_Unpriv - pop {r0} svc #SYSTEM_CALL_xEventGroupWaitBits } + +#endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; @@ -1442,16 +1391,19 @@ __asm EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupClearBits_Unpriv MPU_xEventGroupClearBits_Priv - pop {r0} b MPU_xEventGroupClearBitsImpl MPU_xEventGroupClearBits_Unpriv - pop {r0} svc #SYSTEM_CALL_xEventGroupClearBits } + +#endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; @@ -1464,16 +1416,19 @@ __asm EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSetBits_Unpriv MPU_xEventGroupSetBits_Priv - pop {r0} b MPU_xEventGroupSetBitsImpl MPU_xEventGroupSetBits_Unpriv - pop {r0} svc #SYSTEM_CALL_xEventGroupSetBits } + +#endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_EVENT_GROUPS == 1 ) + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, @@ -1490,17 +1445,18 @@ __asm EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xEventGroupSync_Unpriv MPU_xEventGroupSync_Priv - pop {r0} b MPU_xEventGroupSyncImpl MPU_xEventGroupSync_Unpriv - pop {r0} svc #SYSTEM_CALL_xEventGroupSync } + +#endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */ /*-----------------------------------------------------------*/ -#if ( configUSE_TRACE_FACILITY == 1 ) +#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; @@ -1512,19 +1468,18 @@ __asm UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* FREERTOS_SY push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_uxEventGroupGetNumber_Unpriv MPU_uxEventGroupGetNumber_Priv - pop {r0} b MPU_uxEventGroupGetNumberImpl MPU_uxEventGroupGetNumber_Unpriv - pop {r0} svc #SYSTEM_CALL_uxEventGroupGetNumber } -#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +#endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ -#if ( configUSE_TRACE_FACILITY == 1 ) +#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL; @@ -1538,18 +1493,19 @@ __asm void MPU_vEventGroupSetNumber( void * xEventGroup, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_vEventGroupSetNumber_Unpriv MPU_vEventGroupSetNumber_Priv - pop {r0} b MPU_vEventGroupSetNumberImpl MPU_vEventGroupSetNumber_Unpriv - pop {r0} svc #SYSTEM_CALL_vEventGroupSetNumber } -#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +#endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, size_t xDataLengthBytes, @@ -1566,16 +1522,19 @@ __asm size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSend_Unpriv MPU_xStreamBufferSend_Priv - pop {r0} b MPU_xStreamBufferSendImpl MPU_xStreamBufferSend_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferSend } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, @@ -1592,16 +1551,19 @@ __asm size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferReceive_Unpriv MPU_xStreamBufferReceive_Priv - pop {r0} b MPU_xStreamBufferReceiveImpl MPU_xStreamBufferReceive_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferReceive } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; __asm BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ @@ -1612,16 +1574,19 @@ __asm BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) / push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsFull_Unpriv MPU_xStreamBufferIsFull_Priv - pop {r0} b MPU_xStreamBufferIsFullImpl MPU_xStreamBufferIsFull_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsFull } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; __asm BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ @@ -1632,16 +1597,19 @@ __asm BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferIsEmpty_Unpriv MPU_xStreamBufferIsEmpty_Priv - pop {r0} b MPU_xStreamBufferIsEmptyImpl MPU_xStreamBufferIsEmpty_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferIsEmpty } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; __asm size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ @@ -1652,16 +1620,19 @@ __asm size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffe push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSpacesAvailable_Unpriv MPU_xStreamBufferSpacesAvailable_Priv - pop {r0} b MPU_xStreamBufferSpacesAvailableImpl MPU_xStreamBufferSpacesAvailable_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferSpacesAvailable } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; __asm size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ @@ -1672,16 +1643,19 @@ __asm size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferBytesAvailable_Unpriv MPU_xStreamBufferBytesAvailable_Priv - pop {r0} b MPU_xStreamBufferBytesAvailableImpl MPU_xStreamBufferBytesAvailable_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferBytesAvailable } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; @@ -1694,16 +1668,19 @@ __asm BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamB push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferSetTriggerLevel_Unpriv MPU_xStreamBufferSetTriggerLevel_Priv - pop {r0} b MPU_xStreamBufferSetTriggerLevelImpl MPU_xStreamBufferSetTriggerLevel_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferSetTriggerLevel } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ +#if ( configUSE_STREAM_BUFFERS == 1 ) + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; __asm size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ @@ -1714,14 +1691,15 @@ __asm size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStre push {r0} mrs r0, control tst r0, #1 + pop {r0} bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv MPU_xStreamBufferNextMessageLengthBytes_Priv - pop {r0} b MPU_xStreamBufferNextMessageLengthBytesImpl MPU_xStreamBufferNextMessageLengthBytes_Unpriv - pop {r0} svc #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes } + +#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */ /*-----------------------------------------------------------*/ #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index af4ea632f..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 (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -149,14 +151,14 @@ typedef void ( * portISR_t )( void ); * switches can only occur when uxCriticalNesting is zero. */ PRIVILEGED_DATA static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; -#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) /* * This variable is set to pdTRUE when the scheduler is started. */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; -#endif +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* * Setup the timer to generate the tick interrupts. @@ -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 ]; } @@ -829,7 +839,7 @@ BaseType_t xPortStartScheduler( void ) #endif /* An application can install FreeRTOS interrupt handlers in one of the - * folllowing ways: + * following ways: * 1. Direct Routing - Install the functions vPortSVCHandler and * xPortPendSVHandler for SVCall and PendSV interrupts respectively. * 2. Indirect Routing - Install separate handlers for SVCall and PendSV @@ -852,7 +862,7 @@ BaseType_t xPortStartScheduler( void ) * * Assertion failures here indicate incorrect installation of the * FreeRTOS handlers. For help installing the FreeRTOS handlers, see - * https://www.FreeRTOS.org/FAQHelp.html. + * https://www.freertos.org/Why-FreeRTOS/FAQs. * * Systems with a configurable address for the interrupt vector table * can also encounter assertion failures or even system faults here if @@ -963,11 +973,11 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; - #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) { xSchedulerRunning = pdTRUE; } - #endif + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); @@ -1380,7 +1390,7 @@ void vPortSwitchToUserMode( void ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { extern uint32_t __SRAM_segment_start__; extern uint32_t __SRAM_segment_end__; @@ -1427,7 +1437,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ - if( ulStackDepth > 0 ) + if( uxStackDepth > 0 ) { /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = @@ -1438,13 +1448,13 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, xMPUSettings->xRegion[ 0 ].ulRegionAttribute = ( portMPU_REGION_READ_WRITE ) | ( portMPU_REGION_EXECUTE_NEVER ) | - ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( prvGetMPURegionSizeSetting( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + - ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1UL ); xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); } @@ -1499,45 +1509,58 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ -BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, - uint32_t ulBufferLength, - uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) -{ - uint32_t i, ulBufferStartAddress, ulBufferEndAddress; - BaseType_t xAccessGranted = pdFALSE; - const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { - xAccessGranted = pdTRUE; - } - else - { - if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + + if( xSchedulerRunning == pdFALSE ) { - ulBufferStartAddress = ( uint32_t ) pvBuffer; - ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); - - for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) { - if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, - xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && - portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) { - xAccessGranted = pdTRUE; - break; + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } } } } + + return xAccessGranted; } - return xAccessGranted; -} +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ __asm uint32_t prvPortGetIPSR( void ) @@ -1589,7 +1612,7 @@ __asm uint32_t prvPortGetIPSR( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/RVDS/ARM_CM4_MPU/portmacro.h b/portable/RVDS/ARM_CM4_MPU/portmacro.h index 455aa84cd..8e682ba74 100644 --- a/portable/RVDS/ARM_CM4_MPU/portmacro.h +++ b/portable/RVDS/ARM_CM4_MPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -97,7 +97,7 @@ typedef unsigned long UBaseType_t; #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) @@ -218,7 +218,16 @@ typedef struct MPU_REGION_SETTINGS #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ -#define MAX_CONTEXT_SIZE ( 52 ) +/* + * +---------+---------------+-----------------+-----------------+-----+ + * | s16-s31 | s0-s15, FPSCR | CONTROL, r4-r11 | PSP, r0-r3, r12 | | + * | | | EXC_RETURN | LR, PC, xPSR | | + * +---------+---------------+-----------------+-----------------+-----+ + * + * <--------><---------------><----------------><----------------><----> + * 16 17 10 9 1 + */ +#define MAX_CONTEXT_SIZE ( 53 ) /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) @@ -334,7 +343,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c index 49310786c..33fa80266 100644 --- a/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/portable/RVDS/ARM_CM7/r0p1/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -852,7 +852,7 @@ __asm uint32_t vPortGetIPSR( void ) * * The following links provide detailed information: * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html - * https://www.FreeRTOS.org/FAQHelp.html */ + * https://www.freertos.org/Why-FreeRTOS/FAQs */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); } diff --git a/portable/RVDS/ARM_CM7/r0p1/portmacro.h b/portable/RVDS/ARM_CM7/r0p1/portmacro.h index 2fcf53dfa..b36b427d9 100644 --- a/portable/RVDS/ARM_CM7/r0p1/portmacro.h +++ b/portable/RVDS/ARM_CM7/r0p1/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -165,7 +165,7 @@ extern void vPortExitCritical( void ); #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) /*-----------------------------------------------------------*/ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif diff --git a/portable/Renesas/RX100/port.c b/portable/Renesas/RX100/port.c index 9e8db4f04..a22da66cf 100644 --- a/portable/Renesas/RX100/port.c +++ b/portable/Renesas/RX100/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Renesas/RX100/port_asm.src b/portable/Renesas/RX100/port_asm.src index b3e60a416..afe0aba5b 100644 --- a/portable/Renesas/RX100/port_asm.src +++ b/portable/Renesas/RX100/port_asm.src @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Renesas/RX100/portmacro.h b/portable/Renesas/RX100/portmacro.h index a954bb71c..5ae7d05aa 100644 --- a/portable/Renesas/RX100/portmacro.h +++ b/portable/Renesas/RX100/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -112,7 +112,7 @@ functions are those that end in FromISR. FreeRTOS maintains a separate interrupt API to ensure API function and interrupt entry is as fast and as simple as possible. */ #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/Renesas/RX200/port.c b/portable/Renesas/RX200/port.c index d60ac8fff..fe05cf750 100644 --- a/portable/Renesas/RX200/port.c +++ b/portable/Renesas/RX200/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Renesas/RX200/port_asm.src b/portable/Renesas/RX200/port_asm.src index b3e60a416..afe0aba5b 100644 --- a/portable/Renesas/RX200/port_asm.src +++ b/portable/Renesas/RX200/port_asm.src @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Renesas/RX200/portmacro.h b/portable/Renesas/RX200/portmacro.h index efb9d93c8..bf11b2e93 100644 --- a/portable/Renesas/RX200/portmacro.h +++ b/portable/Renesas/RX200/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -112,7 +112,7 @@ functions are those that end in FromISR. FreeRTOS maintains a separate interrupt API to ensure API function and interrupt entry is as fast and as simple as possible. */ #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/Renesas/RX600/port.c b/portable/Renesas/RX600/port.c index 5438f5764..95431adce 100644 --- a/portable/Renesas/RX600/port.c +++ b/portable/Renesas/RX600/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Renesas/RX600/port_asm.src b/portable/Renesas/RX600/port_asm.src index b3e60a416..afe0aba5b 100644 --- a/portable/Renesas/RX600/port_asm.src +++ b/portable/Renesas/RX600/port_asm.src @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Renesas/RX600/portmacro.h b/portable/Renesas/RX600/portmacro.h index 5ba1c067b..53f45dec7 100644 --- a/portable/Renesas/RX600/portmacro.h +++ b/portable/Renesas/RX600/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -113,7 +113,7 @@ functions are those that end in FromISR. FreeRTOS maintains a separate interrupt API to ensure API function and interrupt entry is as fast and as simple as possible. */ #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/Renesas/RX600v2/port.c b/portable/Renesas/RX600v2/port.c index ee7da87e6..bae8fd623 100644 --- a/portable/Renesas/RX600v2/port.c +++ b/portable/Renesas/RX600v2/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Renesas/RX600v2/port_asm.src b/portable/Renesas/RX600v2/port_asm.src index 6fdcef60d..8d5200b6c 100644 --- a/portable/Renesas/RX600v2/port_asm.src +++ b/portable/Renesas/RX600v2/port_asm.src @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Renesas/RX600v2/portmacro.h b/portable/Renesas/RX600v2/portmacro.h index 630a34eee..0442b05a1 100644 --- a/portable/Renesas/RX600v2/portmacro.h +++ b/portable/Renesas/RX600v2/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -113,7 +113,7 @@ functions are those that end in FromISR. FreeRTOS maintains a separate interrupt API to ensure API function and interrupt entry is as fast and as simple as possible. */ #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/Renesas/RX700v3_DPFPU/port.c b/portable/Renesas/RX700v3_DPFPU/port.c index 26cb9f020..6fec50425 100644 --- a/portable/Renesas/RX700v3_DPFPU/port.c +++ b/portable/Renesas/RX700v3_DPFPU/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Renesas/RX700v3_DPFPU/port_asm.src b/portable/Renesas/RX700v3_DPFPU/port_asm.src index 6fdcef60d..8d5200b6c 100644 --- a/portable/Renesas/RX700v3_DPFPU/port_asm.src +++ b/portable/Renesas/RX700v3_DPFPU/port_asm.src @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Renesas/RX700v3_DPFPU/portmacro.h b/portable/Renesas/RX700v3_DPFPU/portmacro.h index 891024a22..e0c6b1df1 100644 --- a/portable/Renesas/RX700v3_DPFPU/portmacro.h +++ b/portable/Renesas/RX700v3_DPFPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -138,7 +138,7 @@ * interrupt API to ensure API function and interrupt entry is as fast and as * simple as possible. */ #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) - #ifdef configASSERT + #if ( configASSERT_DEFINED == 1 ) #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #else diff --git a/portable/Renesas/SH2A_FPU/ISR_Support.inc b/portable/Renesas/SH2A_FPU/ISR_Support.inc index 3128c526e..33ad2de68 100644 --- a/portable/Renesas/SH2A_FPU/ISR_Support.inc +++ b/portable/Renesas/SH2A_FPU/ISR_Support.inc @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Renesas/SH2A_FPU/port.c b/portable/Renesas/SH2A_FPU/port.c index b5e97e9b1..c14a0a851 100644 --- a/portable/Renesas/SH2A_FPU/port.c +++ b/portable/Renesas/SH2A_FPU/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Renesas/SH2A_FPU/portasm.src b/portable/Renesas/SH2A_FPU/portasm.src index 6164f7644..4cf7225aa 100644 --- a/portable/Renesas/SH2A_FPU/portasm.src +++ b/portable/Renesas/SH2A_FPU/portasm.src @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Renesas/SH2A_FPU/portmacro.h b/portable/Renesas/SH2A_FPU/portmacro.h index e4143e608..2229fd3f6 100644 --- a/portable/Renesas/SH2A_FPU/portmacro.h +++ b/portable/Renesas/SH2A_FPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Rowley/MSP430F449/port.c b/portable/Rowley/MSP430F449/port.c index 992e3e763..392dadbdd 100644 --- a/portable/Rowley/MSP430F449/port.c +++ b/portable/Rowley/MSP430F449/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Rowley/MSP430F449/portasm.h b/portable/Rowley/MSP430F449/portasm.h index 96c27cdac..18361cce3 100644 --- a/portable/Rowley/MSP430F449/portasm.h +++ b/portable/Rowley/MSP430F449/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Rowley/MSP430F449/portext.asm b/portable/Rowley/MSP430F449/portext.asm index f66214134..80cdcef81 100644 --- a/portable/Rowley/MSP430F449/portext.asm +++ b/portable/Rowley/MSP430F449/portext.asm @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Rowley/MSP430F449/portmacro.h b/portable/Rowley/MSP430F449/portmacro.h index 7137a6e09..38304fb03 100644 --- a/portable/Rowley/MSP430F449/portmacro.h +++ b/portable/Rowley/MSP430F449/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/SDCC/Cygnal/port.c b/portable/SDCC/Cygnal/port.c index 8bf739eb7..418a50430 100644 --- a/portable/SDCC/Cygnal/port.c +++ b/portable/SDCC/Cygnal/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/SDCC/Cygnal/portmacro.h b/portable/SDCC/Cygnal/portmacro.h index 04186381f..fe0340757 100644 --- a/portable/SDCC/Cygnal/portmacro.h +++ b/portable/SDCC/Cygnal/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Softune/MB91460/__STD_LIB_sbrk.c b/portable/Softune/MB91460/__STD_LIB_sbrk.c index d328a65fc..4f986e804 100644 --- a/portable/Softune/MB91460/__STD_LIB_sbrk.c +++ b/portable/Softune/MB91460/__STD_LIB_sbrk.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Softune/MB91460/port.c b/portable/Softune/MB91460/port.c index 08e197b06..4b87ba402 100644 --- a/portable/Softune/MB91460/port.c +++ b/portable/Softune/MB91460/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Softune/MB91460/portmacro.h b/portable/Softune/MB91460/portmacro.h index 9ae6959c4..182a3057e 100644 --- a/portable/Softune/MB91460/portmacro.h +++ b/portable/Softune/MB91460/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Softune/MB96340/__STD_LIB_sbrk.c b/portable/Softune/MB96340/__STD_LIB_sbrk.c index d328a65fc..4f986e804 100644 --- a/portable/Softune/MB96340/__STD_LIB_sbrk.c +++ b/portable/Softune/MB96340/__STD_LIB_sbrk.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Softune/MB96340/port.c b/portable/Softune/MB96340/port.c index aef0d65a9..ec0d977bc 100644 --- a/portable/Softune/MB96340/port.c +++ b/portable/Softune/MB96340/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Softune/MB96340/portmacro.h b/portable/Softune/MB96340/portmacro.h index 827874fde..ef4a1eb5a 100644 --- a/portable/Softune/MB96340/portmacro.h +++ b/portable/Softune/MB96340/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Tasking/ARM_CM4F/port.c b/portable/Tasking/ARM_CM4F/port.c index df79a9ac0..43a892f1e 100644 --- a/portable/Tasking/ARM_CM4F/port.c +++ b/portable/Tasking/ARM_CM4F/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/Tasking/ARM_CM4F/port_asm.asm b/portable/Tasking/ARM_CM4F/port_asm.asm index 5a65fb756..8b6784e70 100644 --- a/portable/Tasking/ARM_CM4F/port_asm.asm +++ b/portable/Tasking/ARM_CM4F/port_asm.asm @@ -1,6 +1,6 @@ ;/* ; * FreeRTOS Kernel -; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * SPDX-License-Identifier: MIT ; * diff --git a/portable/Tasking/ARM_CM4F/portmacro.h b/portable/Tasking/ARM_CM4F/portmacro.h index 243e6856b..3d16cd6da 100644 --- a/portable/Tasking/ARM_CM4F/portmacro.h +++ b/portable/Tasking/ARM_CM4F/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ThirdParty/CDK/T-HEAD_CK802/port.c b/portable/ThirdParty/CDK/T-HEAD_CK802/port.c index 6e953a0cb..8f5ab7d26 100644 --- a/portable/ThirdParty/CDK/T-HEAD_CK802/port.c +++ b/portable/ThirdParty/CDK/T-HEAD_CK802/port.c @@ -32,7 +32,7 @@ extern void vPortStartTask( void ); * will be set to 0 prior to the first task being started. */ portLONG ulCriticalNesting = 0x9999UL; -/* Used to record one tack want to swtich task after enter critical area, we need know it +/* Used to record one tack want to switch task after enter critical area, we need know it * and implement task switch after exit critical area */ portLONG pendsvflag = 0; diff --git a/portable/ThirdParty/Community-Supported-Ports b/portable/ThirdParty/Community-Supported-Ports index f051e9bff..bae4c7aa1 160000 --- a/portable/ThirdParty/Community-Supported-Ports +++ b/portable/ThirdParty/Community-Supported-Ports @@ -1 +1 @@ -Subproject commit f051e9bff812aa3c10c5417e064671a1c4eeb314 +Subproject commit bae4c7aa19009825ba48071a8fe25dcb8be84880 diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/port.c b/portable/ThirdParty/GCC/ARC_EM_HS/port.c index 0e023088e..7837f8f73 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/port.c +++ b/portable/ThirdParty/GCC/ARC_EM_HS/port.c @@ -204,7 +204,7 @@ void vPortEndTask( void ) /* * !!! Note !!! * This a trick!!! - * It's a copy from task.c. We need to konw the definition of TCB for the purpose of hardware + * It's a copy from task.c. We need to know the definition of TCB for the purpose of hardware * stack check. Pls don't forget to update it when FreeRTOS is updated. */ typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ diff --git a/portable/ThirdParty/GCC/ARC_v1/port.c b/portable/ThirdParty/GCC/ARC_v1/port.c index 728cd6fac..39e8b771b 100644 --- a/portable/ThirdParty/GCC/ARC_v1/port.c +++ b/portable/ThirdParty/GCC/ARC_v1/port.c @@ -204,7 +204,7 @@ void vPortEndTask( void ) /* * !!! Note !!! * This a trick!!! - * It's a copy from task.c. We need to konw the definition of TCB for the purpose of hardware + * It's a copy from task.c. We need to know the definition of TCB for the purpose of hardware * stack check. Pls don't forget to update it when FreeRTOS is updated. */ typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ diff --git a/portable/ThirdParty/GCC/ARM_TFM/README.md b/portable/ThirdParty/GCC/ARM_TFM/README.md index b1d49fd71..bc594b156 100644 --- a/portable/ThirdParty/GCC/ARM_TFM/README.md +++ b/portable/ThirdParty/GCC/ARM_TFM/README.md @@ -7,16 +7,17 @@ platform. The Platform Security Architecture (PSA) makes it quicker, easier and cheaper to design security into a device from the ground up. PSA is made up of four key -stages: analyze, architect, implement, and certify. See [PSA Resource Page](https://developer.arm.com/architectures/security-architectures/platform-security-architecture). +stages: analyze, architect, implement, and certify. See [PSA Resource Page](https://www.arm.com/architecture/security-features/platform-security). TF-M is an open source project. It provides a reference implementation of PSA -for Arm M-profile architecture. Please get the details from this [link](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/about/). +for Arm M-profile architecture. Please get the details from this [link](https://www.trustedfirmware.org/projects/tf-m/). # Derivation of the source code -* ```os_wrapper_freertos.c``` - The implementation of APIs which are defined in ```\ns_interface\os_wrapper\mutex.h``` by tf-m-tests - (tag: TF-Mv1.5.0 & TF-Mv1.6.0). The implementation is based on FreeRTOS mutex type semaphore. +* `os_wrapper_freertos.c` + The implementation of APIs which are defined in `/interface/include/os_wrapper/mutex.h` + in trusted-firmware-m (tag: TF-Mv2.0.0). The implementation is based on + FreeRTOS mutex type semaphore. # Usage notes @@ -28,53 +29,52 @@ To build a project based on this port: ### Get the TF-M source code -See the [link](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/) to get the source code. This port is supported by TF-M version **tag: TF-Mv1.5.0** & **tag: TF-Mv1.6.0**. +See the [link](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/) to get the source code. This port is supported by TF-M version **tag: TF-Mv2.0.0**. ### Build TF-M -Please refer to this [link](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/tfm/building/tfm_build_instruction.html) to build the secure side. -_**Note:** ```TFM_NS_MANAGE_NSID``` must be configured as "OFF" when building TF-M_. +Please refer to this [link](https://trustedfirmware-m.readthedocs.io/en/latest/getting_started/) to build the secure side. +_**Note:** `TFM_NS_MANAGE_NSID` must be configured as "OFF" when building TF-M_. ## Build the Non-Secure Side -Please copy all the files in ```freertos_kernel\portable\GCC\ARM_CM[23|33|55|85]_NTZ``` into the ```freertos_kernel\portable\ThirdParty\GCC\ARM_TFM``` folder before using this port. Note that TrustZone is enabled in this port. The TF-M runs in the Secure Side. +Please copy all the files in `freertos_kernel/portable/GCC/ARM_CM[23|33|55|85]_NTZ` into the `freertos_kernel/portable/ThirdParty/GCC/ARM_TFM` folder before using this port. Note that TrustZone is enabled in this port. The TF-M runs in the Secure Side. -Please call the API ```tfm_ns_interface_init()``` which is defined in ```\app\tfm_ns_interface.c``` by tf-m-tests -(tag: TF-Mv1.5.0 & TF-Mv1.6.0) at the very beginning of your application. Otherwise, it will always fail when calling a TF-M service in the Nonsecure Side. +Please call the API `tfm_ns_interface_init()` which is defined in `/interface/src/os_wrapper/tfm_ns_interface_rtos.c` by trusted-firmware-m (tag: TF-Mv2.0.0) at the very beginning of your application. Otherwise, it will always fail when calling a TF-M service in the Nonsecure Side. ### Configuration in FreeRTOS kernel -* ```configRUN_FREERTOS_SECURE_ONLY``` +* `configRUN_FREERTOS_SECURE_ONLY` This macro should be configured as 0. In this port, TF-M runs in the Secure Side while FreeRTOS Kernel runs in the Non-Secure Side. -* ```configENABLE_FPU``` +* `configENABLE_FPU` 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``` +* `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``` +* `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. ### Integrate TF-M Non-Secure interface with FreeRTOS project To enable calling TF-M services by the Non-Secure Side, the files below should be included in the FreeRTOS project and built together. -* files in ```trusted-firmware-m\build\install\interface\src``` +* files in `trusted-firmware-m/build/api_ns/interface/src` These files contain the implementation of PSA Functional Developer APIs which can be called by Non-Secure Side directly and PSA Firmware Framework APIs in the IPC model. These files should be taken as part of the Non-Secure source code. -* files in ```trusted-firmware-m\build\install\interface\include``` +* files in `trusted-firmware-m/build/api_ns/interface/include` These files are the necessary header files to call TF-M services. -* ```trusted-firmware-m\build\install\interface\lib\s_veneers.o``` +* `trusted-firmware-m/build/api_ns/interface/lib/s_veneers.o` This object file contains all the Non-Secure callable functions exported by TF-M and it should be linked when generating the Non-Secure image. -*Copyright (c) 2020-2022, Arm Limited. All rights reserved.* +*Copyright (c) 2020-2024, Arm Limited. All rights reserved.* diff --git a/portable/ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c b/portable/ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c index 8eb453930..35add2b5a 100644 --- a/portable/ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c +++ b/portable/ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * Copyright (c) 2019-2024, Arm Limited. All rights reserved. * * SPDX-License-Identifier: MIT * @@ -24,8 +24,8 @@ /* * This file contains the implementation of APIs which are defined in - * os_wrapper/mutex.h by TF-M(tag: TF-Mv1.1). The implementation is based - * on FreeRTOS mutex type semaphore. + * \interface/include/os_wrapper/mutex.h by TF-M(tag: TF-Mv2.0.0). + * The implementation is based on FreeRTOS mutex type semaphore. */ #include "os_wrapper/mutex.h" diff --git a/portable/ThirdParty/GCC/ATmega/port.c b/portable/ThirdParty/GCC/ATmega/port.c index fa71552b3..168bcdd94 100644 --- a/portable/ThirdParty/GCC/ATmega/port.c +++ b/portable/ThirdParty/GCC/ATmega/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -100,11 +100,11 @@ extern volatile TCB_t * volatile pxCurrentTCB; { __asm__ __volatile__ ( "in __tmp_reg__,__SREG__" "\n\t" - "cli" "\n\t" - "wdr" "\n\t" - "out %0, %1" "\n\t" - "out __SREG__,__tmp_reg__" "\n\t" - "out %0, %2" "\n\t" + "cli" "\n\t" + "wdr" "\n\t" + "out %0, %1" "\n\t" + "out __SREG__,__tmp_reg__" "\n\t" + "out %0, %2" "\n\t" : /* no outputs */ : "I" ( _SFR_IO_ADDR( _WD_CONTROL_REG ) ), "r" ( ( uint8_t ) ( _BV( _WD_CHANGE_BIT ) | _BV( WDE ) ) ), @@ -117,11 +117,11 @@ extern volatile TCB_t * volatile pxCurrentTCB; { __asm__ __volatile__ ( "in __tmp_reg__,__SREG__" "\n\t" - "cli" "\n\t" - "wdr" "\n\t" - "sts %0, %1" "\n\t" - "out __SREG__,__tmp_reg__" "\n\t" - "sts %0, %2" "\n\t" + "cli" "\n\t" + "wdr" "\n\t" + "sts %0, %1" "\n\t" + "out __SREG__,__tmp_reg__" "\n\t" + "sts %0, %2" "\n\t" : /* no outputs */ : "n" ( _SFR_MEM_ADDR( _WD_CONTROL_REG ) ), "r" ( ( uint8_t ) ( _BV( _WD_CHANGE_BIT ) | _BV( WDE ) ) ), @@ -167,11 +167,11 @@ extern volatile TCB_t * volatile pxCurrentTCB; { __asm__ __volatile__ ( "in __tmp_reg__,__SREG__" "\n\t" - "cli" "\n\t" - "wdr" "\n\t" - "out %0, %1" "\n\t" - "out __SREG__,__tmp_reg__" "\n\t" - "out %0, %2" "\n\t" + "cli" "\n\t" + "wdr" "\n\t" + "out %0, %1" "\n\t" + "out __SREG__,__tmp_reg__" "\n\t" + "out %0, %2" "\n\t" : /* no outputs */ : "I" ( _SFR_IO_ADDR( _WD_CONTROL_REG ) ), "r" ( ( uint8_t ) ( _BV( _WD_CHANGE_BIT ) | _BV( WDE ) ) ), @@ -184,11 +184,11 @@ extern volatile TCB_t * volatile pxCurrentTCB; { __asm__ __volatile__ ( "in __tmp_reg__,__SREG__" "\n\t" - "cli" "\n\t" - "wdr" "\n\t" - "sts %0, %1" "\n\t" - "out __SREG__,__tmp_reg__" "\n\t" - "sts %0, %2" "\n\t" + "cli" "\n\t" + "wdr" "\n\t" + "sts %0, %1" "\n\t" + "out __SREG__,__tmp_reg__" "\n\t" + "sts %0, %2" "\n\t" : /* no outputs */ : "n" ( _SFR_MEM_ADDR( _WD_CONTROL_REG ) ), "r" ( ( uint8_t ) ( _BV( _WD_CHANGE_BIT ) | _BV( WDE ) ) ), diff --git a/portable/ThirdParty/GCC/ATmega/portmacro.h b/portable/ThirdParty/GCC/ATmega/portmacro.h index 7f8205497..0cc583479 100644 --- a/portable/ThirdParty/GCC/ATmega/portmacro.h +++ b/portable/ThirdParty/GCC/ATmega/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -73,20 +73,20 @@ typedef uint8_t UBaseType_t; /* Critical section management. */ -#define portENTER_CRITICAL() \ - __asm__ __volatile__ ( \ - "in __tmp_reg__, __SREG__" "\n\t" \ - "cli" "\n\t" \ - "push __tmp_reg__" "\n\t" \ - ::: "memory" \ +#define portENTER_CRITICAL() \ + __asm__ __volatile__ ( \ + "in __tmp_reg__, __SREG__" "\n\t" \ + "cli" "\n\t" \ + "push __tmp_reg__" "\n\t" \ + ::: "memory" \ ) -#define portEXIT_CRITICAL() \ - __asm__ __volatile__ ( \ - "pop __tmp_reg__" "\n\t" \ - "out __SREG__, __tmp_reg__" "\n\t" \ - ::: "memory" \ +#define portEXIT_CRITICAL() \ + __asm__ __volatile__ ( \ + "pop __tmp_reg__" "\n\t" \ + "out __SREG__, __tmp_reg__" "\n\t" \ + ::: "memory" \ ) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 5dc3d73e2..a1b1ca8c7 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -48,11 +48,19 @@ * 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, +* 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` *----------------------------------------------------------*/ +#ifdef __linux__ + #define _GNU_SOURCE +#endif #include "portmacro.h" - #include #include +#include #include #include #include @@ -60,10 +68,7 @@ #include #include #include - -#ifdef __APPLE__ - #include -#endif +#include /* Scheduler includes. */ #include "FreeRTOS.h" @@ -97,13 +102,16 @@ static inline Thread_t * prvGetThreadFromTask( TaskHandle_t xTask ) /*-----------------------------------------------------------*/ static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT; +static pthread_once_t hThreadKeyOnce = PTHREAD_ONCE_INIT; static sigset_t xAllSignals; static sigset_t xSchedulerOriginalSignalMask; static pthread_t hMainThread = ( pthread_t ) NULL; static volatile BaseType_t uxCriticalNesting; -/*-----------------------------------------------------------*/ - static BaseType_t xSchedulerEnd = pdFALSE; +static pthread_t hTimerTickThread; +static bool xTimerTickThreadShouldRun; +static uint64_t prvStartTimeNs; +static pthread_key_t xThreadKey = 0; /*-----------------------------------------------------------*/ static void prvSetupSignalsAndSchedulerPolicy( void ); @@ -116,6 +124,64 @@ static void prvResumeThread( Thread_t * xThreadId ); static void vPortSystemTickHandler( int sig ); static void vPortStartFirstTask( void ); static void prvPortYieldFromISR( void ); +static void prvThreadKeyDestructor( void * pvData ); +static void prvInitThreadKey( void ); +static void prvMarkAsFreeRTOSThread( void ); +static BaseType_t prvIsFreeRTOSThread( void ); +static void prvDestroyThreadKey( void ); +/*-----------------------------------------------------------*/ + +static void prvThreadKeyDestructor( void * pvData ) +{ + free( pvData ); +} +/*-----------------------------------------------------------*/ + +static void prvInitThreadKey( void ) +{ + pthread_key_create( &xThreadKey, prvThreadKeyDestructor ); + /* Destroy xThreadKey when the process exits. */ + atexit( prvDestroyThreadKey ); +} +/*-----------------------------------------------------------*/ + +static void prvMarkAsFreeRTOSThread( void ) +{ + uint8_t * pucThreadData = NULL; + + ( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); + + pucThreadData = malloc( 1 ); + configASSERT( pucThreadData != NULL ); + + *pucThreadData = 1; + + pthread_setspecific( xThreadKey, pucThreadData ); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsFreeRTOSThread( void ) +{ + uint8_t * pucThreadData = NULL; + BaseType_t xRet = pdFALSE; + + ( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); + + pucThreadData = ( uint8_t * ) pthread_getspecific( xThreadKey ); + + if( ( pucThreadData != NULL ) && ( *pucThreadData == 1 ) ) + { + xRet = pdTRUE; + } + + return xRet; +} +/*-----------------------------------------------------------*/ + +static void prvDestroyThreadKey( void ) +{ + pthread_key_delete( xThreadKey ); +} /*-----------------------------------------------------------*/ static void prvFatalError( const char * pcCall, @@ -127,6 +193,17 @@ void prvFatalError( const char * pcCall, fprintf( stderr, "%s: %s\n", pcCall, strerror( iErrno ) ); abort(); } +/*-----------------------------------------------------------*/ + +static void prvPortSetCurrentThreadName( const char * pxThreadName ) +{ + #ifdef __APPLE__ + pthread_setname_np( pxThreadName ); + #else + pthread_setname_np( pthread_self(), pxThreadName ); + #endif +} +/*-----------------------------------------------------------*/ /* * See header file for description. @@ -149,28 +226,16 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, thread = ( Thread_t * ) ( pxTopOfStack + 1 ) - 1; pxTopOfStack = ( StackType_t * ) thread - 1; - #ifdef __APPLE__ - pxEndOfStack = ( StackType_t * ) mach_vm_round_page( pxEndOfStack ); - #endif - + /* Ensure that there is enough space to store Thread_t on the stack. */ ulStackSize = ( size_t ) ( pxTopOfStack + 1 - pxEndOfStack ) * sizeof( *pxTopOfStack ); - - #ifdef __APPLE__ - ulStackSize = mach_vm_trunc_page( ulStackSize ); - #endif + configASSERT( ulStackSize > sizeof( Thread_t ) ); + ( void ) ulStackSize; /* suppress set but not used warning */ thread->pxCode = pxCode; thread->pvParams = pvParameters; thread->xDying = pdFALSE; pthread_attr_init( &xThreadAttributes ); - iRet = pthread_attr_setstack( &xThreadAttributes, pxEndOfStack, ulStackSize ); - - if( iRet != 0 ) - { - fprintf( stderr, "[WARN] pthread_attr_setstack failed with return value: %d. Default stack will be used.\n", iRet ); - fprintf( stderr, "[WARN] Increase the stack size to PTHREAD_STACK_MIN.\n" ); - } thread->ev = event_create(); @@ -208,6 +273,7 @@ BaseType_t xPortStartScheduler( void ) sigset_t xSignals; hMainThread = pthread_self(); + prvPortSetCurrentThreadName( "Scheduler" ); /* Start the timer that generates the tick ISR(SIGALRM). * Interrupts are disabled here already. */ @@ -231,15 +297,23 @@ BaseType_t xPortStartScheduler( void ) sigwait( &xSignals, &iSignal ); } - /* Cancel the Idle task and free its resources */ - #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) - vPortCancelThread( xTaskGetIdleTaskHandle() ); - #endif + /* + * clear out the variable that is used to end the scheduler, otherwise + * subsequent scheduler restarts will end immediately. + */ + xSchedulerEnd = pdFALSE; - #if ( configUSE_TIMERS == 1 ) - /* Cancel the Timer task and free its resources */ - vPortCancelThread( xTimerGetTimerDaemonTaskHandle() ); - #endif /* configUSE_TIMERS */ + /* Reset pthread_once_t, needed to restart the scheduler again. + * memset the internal struct members for MacOS/Linux Compatibility */ + #if __APPLE__ + hSigSetupThread.__sig = _PTHREAD_ONCE_SIG_init; + hThreadKeyOnce.__sig = _PTHREAD_ONCE_SIG_init; + memset( ( void * ) &hSigSetupThread.__opaque, 0, sizeof( hSigSetupThread.__opaque ) ); + memset( ( void * ) &hThreadKeyOnce.__opaque, 0, sizeof( hThreadKeyOnce.__opaque ) ); + #else /* Linux PTHREAD library*/ + hSigSetupThread = ( pthread_once_t ) PTHREAD_ONCE_INIT; + hThreadKeyOnce = ( pthread_once_t ) PTHREAD_ONCE_INIT; + #endif /* __APPLE__*/ /* Restore original signal mask. */ ( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL ); @@ -250,30 +324,30 @@ BaseType_t xPortStartScheduler( void ) void vPortEndScheduler( void ) { - struct itimerval itimer; - struct sigaction sigtick; - Thread_t * xCurrentThread; + Thread_t * pxCurrentThread; + BaseType_t xIsFreeRTOSThread; - /* Stop the timer and ignore any pending SIGALRMs that would end - * up running on the main thread when it is resumed. */ - itimer.it_value.tv_sec = 0; - itimer.it_value.tv_usec = 0; + /* Stop the timer tick thread. */ + xTimerTickThreadShouldRun = false; + pthread_join( hTimerTickThread, NULL ); - itimer.it_interval.tv_sec = 0; - itimer.it_interval.tv_usec = 0; - ( void ) setitimer( ITIMER_REAL, &itimer, NULL ); - - sigtick.sa_flags = 0; - sigtick.sa_handler = SIG_IGN; - sigemptyset( &sigtick.sa_mask ); - sigaction( SIGALRM, &sigtick, 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 ); - xCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); - prvSuspendSelf( xCurrentThread ); + /* Waiting to be deleted here. */ + if( xIsFreeRTOSThread == pdTRUE ) + { + pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); + event_wait( pxCurrentThread->ev ); + } + + pthread_testcancel(); } /*-----------------------------------------------------------*/ @@ -317,6 +391,10 @@ static void prvPortYieldFromISR( void ) void vPortYield( void ) { + /* This must never be called from outside of a FreeRTOS-owned thread, or + * the thread could get stuck in a suspended state. */ + configASSERT( prvIsFreeRTOSThread() == pdTRUE ); + vPortEnterCritical(); prvPortYieldFromISR(); @@ -327,13 +405,19 @@ void vPortYield( void ) void vPortDisableInterrupts( void ) { - pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL ); + if( prvIsFreeRTOSThread() == pdTRUE ) + { + pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL ); + } } /*-----------------------------------------------------------*/ void vPortEnableInterrupts( void ) { - pthread_sigmask( SIG_UNBLOCK, &xAllSignals, NULL ); + if( prvIsFreeRTOSThread() == pdTRUE ) + { + pthread_sigmask( SIG_UNBLOCK, &xAllSignals, NULL ); + } } /*-----------------------------------------------------------*/ @@ -359,45 +443,43 @@ static uint64_t prvGetTimeNs( void ) return ( uint64_t ) t.tv_sec * ( uint64_t ) 1000000000UL + ( uint64_t ) t.tv_nsec; } - -static uint64_t prvStartTimeNs; +/*-----------------------------------------------------------*/ /* commented as part of the code below in vPortSystemTickHandler, * to adjust timing according to full demo requirements */ /* static uint64_t prvTickCount; */ +static void * prvTimerTickHandler( void * arg ) +{ + ( void ) arg; + + prvMarkAsFreeRTOSThread(); + + prvPortSetCurrentThreadName( "Scheduler timer" ); + + while( xTimerTickThreadShouldRun ) + { + /* + * signal to the active task to cause tick handling or + * preemption (if enabled) + */ + Thread_t * thread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); + pthread_kill( thread->pthread, SIGALRM ); + usleep( portTICK_RATE_MICROSECONDS ); + } + + return NULL; +} +/*-----------------------------------------------------------*/ + /* * Setup the systick timer to generate the tick interrupts at the required * frequency. */ void prvSetupTimerInterrupt( void ) { - struct itimerval itimer; - int iRet; - - /* Initialise the structure with the current timer information. */ - iRet = getitimer( ITIMER_REAL, &itimer ); - - if( iRet == -1 ) - { - prvFatalError( "getitimer", errno ); - } - - /* Set the interval between timer events. */ - itimer.it_interval.tv_sec = 0; - itimer.it_interval.tv_usec = portTICK_RATE_MICROSECONDS; - - /* Set the current count-down. */ - itimer.it_value.tv_sec = 0; - itimer.it_value.tv_usec = portTICK_RATE_MICROSECONDS; - - /* Set-up the timer interrupt. */ - iRet = setitimer( ITIMER_REAL, &itimer, NULL ); - - if( iRet == -1 ) - { - prvFatalError( "setitimer", errno ); - } + xTimerTickThreadShouldRun = true; + pthread_create( &hTimerTickThread, NULL, prvTimerTickHandler, NULL ); prvStartTimeNs = prvGetTimeNs(); } @@ -405,43 +487,33 @@ void prvSetupTimerInterrupt( void ) static void vPortSystemTickHandler( int sig ) { - Thread_t * pxThreadToSuspend; - Thread_t * pxThreadToResume; + if( prvIsFreeRTOSThread() == pdTRUE ) + { + Thread_t * pxThreadToSuspend; + Thread_t * pxThreadToResume; - ( void ) sig; + ( void ) sig; -/* uint64_t xExpectedTicks; */ + uxCriticalNesting++; /* Signals are blocked in this signal handler. */ - uxCriticalNesting++; /* Signals are blocked in this signal handler. */ - - #if ( configUSE_PREEMPTION == 1 ) pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); - #endif - /* Tick Increment, accounting for any lost signals or drift in - * the timer. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Select Next Task. */ + vTaskSwitchContext(); -/* - * Comment code to adjust timing according to full demo requirements - * xExpectedTicks = (prvGetTimeNs() - prvStartTimeNs) - * / (portTICK_RATE_MICROSECONDS * 1000); - * do { */ - xTaskIncrementTick(); + pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); -/* prvTickCount++; - * } while (prvTickCount < xExpectedTicks); - */ + prvSwitchThread( pxThreadToResume, pxThreadToSuspend ); + } - #if ( configUSE_PREEMPTION == 1 ) - /* Select Next Task. */ - vTaskSwitchContext(); - - pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); - - prvSwitchThread( pxThreadToResume, pxThreadToSuspend ); - #endif - - uxCriticalNesting--; + uxCriticalNesting--; + } + else + { + fprintf( stderr, "vPortSystemTickHandler called from non-FreeRTOS thread\n" ); + } } /*-----------------------------------------------------------*/ @@ -454,6 +526,7 @@ void vPortThreadDying( void * pxTaskToDelete, pxThread->xDying = pdTRUE; } +/*-----------------------------------------------------------*/ void vPortCancelThread( void * pxTaskToDelete ) { @@ -463,6 +536,7 @@ void vPortCancelThread( void * pxTaskToDelete ) * The thread has already been suspended so it can be safely cancelled. */ pthread_cancel( pxThreadToCancel->pthread ); + event_signal( pxThreadToCancel->ev ); pthread_join( pxThreadToCancel->pthread, NULL ); event_delete( pxThreadToCancel->ev ); } @@ -472,12 +546,17 @@ static void * prvWaitForStart( void * pvParams ) { Thread_t * pxThread = pvParams; + prvMarkAsFreeRTOSThread(); + prvSuspendSelf( pxThread ); /* Resumed for the first time, unblocks all signals. */ uxCriticalNesting = 0; vPortEnableInterrupts(); + /* Set thread name */ + prvPortSetCurrentThreadName( pcTaskGetName( xTaskGetCurrentTaskHandle() ) ); + /* Call the task's entry point. */ pxThread->pxCode( pxThread->pvParams ); @@ -538,6 +617,7 @@ static void prvSuspendSelf( Thread_t * thread ) * - A thread with all signals blocked with pthread_sigmask(). */ event_wait( thread->ev ); + pthread_testcancel(); } /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/Posix/portmacro.h b/portable/ThirdParty/GCC/Posix/portmacro.h index 6de25da45..e117749fe 100644 --- a/portable/ThirdParty/GCC/Posix/portmacro.h +++ b/portable/ThirdParty/GCC/Posix/portmacro.h @@ -64,7 +64,7 @@ typedef long BaseType_t; typedef unsigned long UBaseType_t; typedef unsigned long TickType_t; -#define portMAX_DELAY ( TickType_t ) ULONG_MAX +#define portMAX_DELAY ( ( TickType_t ) ULONG_MAX ) #define portTICK_TYPE_IS_ATOMIC 1 @@ -135,7 +135,7 @@ extern void vPortCancelThread( void * pxTaskToDelete ); * are always a full memory barrier. ISRs are emulated as signals * which also imply a full memory barrier. * - * Thus, only a compilier barrier is needed to prevent the compiler + * Thus, only a compiler barrier is needed to prevent the compiler * reordering. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) diff --git a/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c index ead6cdb07..55fd7bbfc 100644 --- a/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c +++ b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -35,30 +35,49 @@ struct event { pthread_mutex_t mutex; + pthread_mutexattr_t mutexattr; pthread_cond_t cond; bool event_triggered; }; +/*-----------------------------------------------------------*/ struct event * event_create( void ) { struct event * ev = malloc( sizeof( struct event ) ); - ev->event_triggered = false; - pthread_mutex_init( &ev->mutex, NULL ); - pthread_cond_init( &ev->cond, NULL ); + if( ev != NULL ) + { + ev->event_triggered = false; + pthread_mutexattr_init( &ev->mutexattr ); + #ifndef __APPLE__ + pthread_mutexattr_setrobust( &ev->mutexattr, PTHREAD_MUTEX_ROBUST ); + #endif + pthread_mutex_init( &ev->mutex, &ev->mutexattr ); + pthread_cond_init( &ev->cond, NULL ); + } + return ev; } +/*-----------------------------------------------------------*/ void event_delete( struct event * ev ) { pthread_mutex_destroy( &ev->mutex ); + pthread_mutexattr_destroy( &ev->mutexattr ); pthread_cond_destroy( &ev->cond ); free( ev ); } +/*-----------------------------------------------------------*/ bool event_wait( struct event * ev ) { - pthread_mutex_lock( &ev->mutex ); + if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD ) + { + #ifndef __APPLE__ + /* If the thread owning the mutex died, make the mutex consistent. */ + pthread_mutex_consistent( &ev->mutex ); + #endif + } while( ev->event_triggered == false ) { @@ -69,6 +88,8 @@ bool event_wait( struct event * ev ) pthread_mutex_unlock( &ev->mutex ); return true; } +/*-----------------------------------------------------------*/ + bool event_wait_timed( struct event * ev, time_t ms ) { @@ -78,7 +99,13 @@ bool event_wait_timed( struct event * ev, clock_gettime( CLOCK_REALTIME, &ts ); ts.tv_sec += ms / 1000; ts.tv_nsec += ( ( ms % 1000 ) * 1000000 ); - pthread_mutex_lock( &ev->mutex ); + if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD ) + { + #ifndef __APPLE__ + /* If the thread owning the mutex died, make the mutex consistent. */ + pthread_mutex_consistent( &ev->mutex ); + #endif + } while( ( ev->event_triggered == false ) && ( ret == 0 ) ) { @@ -94,11 +121,19 @@ bool event_wait_timed( struct event * ev, pthread_mutex_unlock( &ev->mutex ); return true; } +/*-----------------------------------------------------------*/ void event_signal( struct event * ev ) { - pthread_mutex_lock( &ev->mutex ); + if( pthread_mutex_lock( &ev->mutex ) == EOWNERDEAD ) + { + #ifndef __APPLE__ + /* If the thread owning the mutex died, make the mutex consistent. */ + pthread_mutex_consistent( &ev->mutex ); + #endif + } ev->event_triggered = true; pthread_cond_signal( &ev->cond ); pthread_mutex_unlock( &ev->mutex ); } +/*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/Posix/utils/wait_for_event.h b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.h index 6f6efa3ea..533db04f1 100644 --- a/portable/ThirdParty/GCC/Posix/utils/wait_for_event.h +++ b/portable/ThirdParty/GCC/Posix/utils/wait_for_event.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake b/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake index 109a54e19..854aab43f 100644 --- a/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake +++ b/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake @@ -10,38 +10,68 @@ if (DEFINED ENV{FREERTOS_KERNEL_PATH} AND (NOT FREERTOS_KERNEL_PATH)) message("Using FREERTOS_KERNEL_PATH from environment ('${FREERTOS_KERNEL_PATH}')") endif () -set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC/RP2040") -# undo the above -set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") - -if (NOT FREERTOS_KERNEL_PATH) - # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) - get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) - get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) - if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) - get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) +# first pass we look in old tree; second pass we look in new tree +foreach(SEARCH_PASS RANGE 0 1) + if (SEARCH_PASS) + # ports may be moving to submodule in the future + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/Community-Supported-Ports/GCC") + set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../../..") + else() + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC") + set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") endif() - if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) - get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) - message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") - elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") - set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) - message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") - endif() -endif () -if (NOT FREERTOS_KERNEL_PATH) - foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) - # check if FreeRTOS-Kernel exists under directory that included us - set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) - get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) - if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) - get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) - message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") + if(PICO_PLATFORM STREQUAL "rp2040") + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2040") + else() + if (PICO_PLATFORM STREQUAL "rp2350-riscv") + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_RISC-V") + else() + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_ARM_NTZ") + endif() + endif() + + if (NOT FREERTOS_KERNEL_PATH) + # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) + get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) + get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + endif() + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") + break() + elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") + set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) + message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") break() endif() - endforeach() -endif() + endif () + + if (NOT FREERTOS_KERNEL_PATH) + foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) + # check if FreeRTOS-Kernel exists under directory that included us + set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) + get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) + if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) + get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") + break() + endif() + endforeach() + if (FREERTOS_KERNEL_PATH) + break() + endif() + endif() + + # user must have specified + if (FREERTOS_KERNEL_PATH) + if (EXISTS "${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") + break() + endif() + endif() +endforeach () if (NOT FREERTOS_KERNEL_PATH) message(FATAL_ERROR "FreeRTOS location was not specified. Please set FREERTOS_KERNEL_PATH.") @@ -54,8 +84,8 @@ if (NOT EXISTS ${FREERTOS_KERNEL_PATH}) message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' not found") endif() if (NOT EXISTS ${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) - message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain an RP2040 port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") + message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain a '${PICO_PLATFORM}' port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") endif() set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} CACHE PATH "Path to the FreeRTOS_KERNEL" FORCE) -add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) +add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) \ No newline at end of file diff --git a/portable/ThirdParty/GCC/RP2040/README.md b/portable/ThirdParty/GCC/RP2040/README.md index bd521d53f..5db8702c5 100644 --- a/portable/ThirdParty/GCC/RP2040/README.md +++ b/portable/ThirdParty/GCC/RP2040/README.md @@ -26,7 +26,7 @@ This will locate the FreeRTOS kernel if it is a direct sub-module of your projec version, you can include the FreeRTOS-Kernel support later in your CMake build (possibly in a subdirectory) and the FreeRTOS-Kernel support will only apply to those targets which explicitly include FreeRTOS support. -As an alternative to the `import` statement above, you can just add this directory directly via thw following (with +As an alternative to the `import` statement above, you can just add this directory directly via the following (with the same placement restrictions related to the Raspberry Pi Pico SDK version above): ```cmake diff --git a/portable/ThirdParty/GCC/RP2040/idle_task_static_memory.c b/portable/ThirdParty/GCC/RP2040/idle_task_static_memory.c deleted file mode 100644 index aaeec1881..000000000 --- a/portable/ThirdParty/GCC/RP2040/idle_task_static_memory.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: MIT AND BSD-3-Clause - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#include "FreeRTOS.h" - -void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, - StackType_t ** ppxIdleTaskStackBuffer, - uint32_t * pulIdleTaskStackSize ) -{ - /* If the buffers to be provided to the Idle task are declared inside this - * function then they must be declared static - otherwise they will be allocated on - * the stack and so not exists after this function exits. */ - static StaticTask_t xIdleTaskTCB; - static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; - - /* Pass out a pointer to the StaticTask_t structure in which the Idle task's - * state will be stored. */ - *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; - - /* Pass out the array that will be used as the Idle task's stack. */ - *ppxIdleTaskStackBuffer = uxIdleTaskStack; - - /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. - * Note that, as the array is necessarily of type StackType_t, - * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ - *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; -} diff --git a/portable/ThirdParty/GCC/RP2040/include/freertos_sdk_config.h b/portable/ThirdParty/GCC/RP2040/include/freertos_sdk_config.h index bf9fdca5e..71ca3277e 100644 --- a/portable/ThirdParty/GCC/RP2040/include/freertos_sdk_config.h +++ b/portable/ThirdParty/GCC/RP2040/include/freertos_sdk_config.h @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h index 2b3f822b5..3e54f384f 100644 --- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h +++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: MIT AND BSD-3-Clause @@ -83,7 +83,7 @@ typedef uint32_t UBaseType_t; #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) -/* We have to use PICO_DIVIDER_DISABLE_INTERRUPTS as the source of truth rathern than our config, +/* We have to use PICO_DIVIDER_DISABLE_INTERRUPTS as the source of truth rather than our config, * as our FreeRTOSConfig.h header cannot be included by ASM code - which is what this affects in the SDK */ #define portUSE_DIVIDER_SAVE_RESTORE !PICO_DIVIDER_DISABLE_INTERRUPTS #if portUSE_DIVIDER_SAVE_RESTORE @@ -151,16 +151,17 @@ extern void vPortYield( void ); void vYieldCore( int xCoreID ); #define portYIELD_CORE( a ) vYieldCore( a ) -#define portRESTORE_INTERRUPTS( ulState ) __asm volatile ( "msr PRIMASK,%0" ::"r" ( ulState ) : ) /*-----------------------------------------------------------*/ /* Critical nesting count management. */ +#define portCRITICAL_NESTING_IN_TCB 0 + extern UBaseType_t uxCriticalNestings[ configNUMBER_OF_CORES ]; -#define portGET_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ] ) -#define portSET_CRITICAL_NESTING_COUNT( x ) ( uxCriticalNestings[ portGET_CORE_ID() ] = ( x ) ) -#define portINCREMENT_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ]++ ) -#define portDECREMENT_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ]-- ) +#define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ] ) +#define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( uxCriticalNestings[ ( xCoreID ) ] = ( x ) ) +#define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ]++ ) +#define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ]-- ) /*-----------------------------------------------------------*/ @@ -181,9 +182,7 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( nake #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) - -extern void vPortEnableInterrupts(); -#define portENABLE_INTERRUPTS() vPortEnableInterrupts() +#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #if ( configNUMBER_OF_CORES == 1 ) extern void vPortEnterCritical( void ); @@ -203,66 +202,64 @@ extern void vPortEnableInterrupts(); #define portRTOS_SPINLOCK_COUNT 2 +#if PICO_SDK_VERSION_MAJOR < 2 +__force_inline static bool spin_try_lock_unsafe(spin_lock_t *lock) { + return *lock; +} +#endif + /* Note this is a single method with uxAcquire parameter since we have * static vars, the method is always called with a compile time constant for - * uxAcquire, and the compiler should dothe right thing! */ -static inline void vPortRecursiveLock( uint32_t ulLockNum, + * uxAcquire, and the compiler should do the right thing! */ +static inline void vPortRecursiveLock( BaseType_t xCoreID, + uint32_t ulLockNum, spin_lock_t * pxSpinLock, BaseType_t uxAcquire ) { - static uint8_t ucOwnedByCore[ portMAX_CORE_COUNT ]; - static uint8_t ucRecursionCountByLock[ portRTOS_SPINLOCK_COUNT ]; + static volatile uint8_t ucOwnedByCore[ portMAX_CORE_COUNT ][portRTOS_SPINLOCK_COUNT]; + static volatile uint8_t ucRecursionCountByLock[ portRTOS_SPINLOCK_COUNT ]; configASSERT( ulLockNum < portRTOS_SPINLOCK_COUNT ); - uint32_t ulCoreNum = get_core_num(); - uint32_t ulLockBit = 1u << ulLockNum; - configASSERT( ulLockBit < 256u ); if( uxAcquire ) { - if( __builtin_expect( !*pxSpinLock, 0 ) ) - { - if( ucOwnedByCore[ ulCoreNum ] & ulLockBit ) + if (!spin_try_lock_unsafe(pxSpinLock)) { + if( ucOwnedByCore[ xCoreID ][ ulLockNum ] ) { configASSERT( ucRecursionCountByLock[ ulLockNum ] != 255u ); - ucRecursionCountByLock[ ulLockNum ]++; + ucRecursionCountByLock[ ulLockNum ] = ucRecursionCountByLock[ ulLockNum ] + 1; return; } - - while( __builtin_expect( !*pxSpinLock, 0 ) ) - { - } + spin_lock_unsafe_blocking(pxSpinLock); } - - __mem_fence_acquire(); configASSERT( ucRecursionCountByLock[ ulLockNum ] == 0 ); ucRecursionCountByLock[ ulLockNum ] = 1; - ucOwnedByCore[ ulCoreNum ] |= ulLockBit; + ucOwnedByCore[ xCoreID ][ ulLockNum ] = 1; } else { - configASSERT( ( ucOwnedByCore[ ulCoreNum ] & ulLockBit ) != 0 ); + configASSERT( ( ucOwnedByCore[ xCoreID ] [ulLockNum ] ) != 0 ); configASSERT( ucRecursionCountByLock[ ulLockNum ] != 0 ); - if( !--ucRecursionCountByLock[ ulLockNum ] ) + ucRecursionCountByLock[ ulLockNum ] = ucRecursionCountByLock[ ulLockNum ] - 1; + if ( ucRecursionCountByLock[ ulLockNum ] == 0U ) { - ucOwnedByCore[ ulCoreNum ] &= ~ulLockBit; - __mem_fence_release(); - *pxSpinLock = 1; + ucOwnedByCore[ xCoreID ] [ ulLockNum ] = 0; + spin_unlock_unsafe(pxSpinLock); } } } #if ( configNUMBER_OF_CORES == 1 ) - #define portGET_ISR_LOCK() - #define portRELEASE_ISR_LOCK() - #define portGET_TASK_LOCK() - #define portRELEASE_TASK_LOCK() + #define portGET_ISR_LOCK( xCoreID ) + #define portRELEASE_ISR_LOCK( xCoreID ) + #define portGET_TASK_LOCK( xCoreID ) + #define portRELEASE_TASK_LOCK( xCoreID ) #else - #define portGET_ISR_LOCK() vPortRecursiveLock( 0, spin_lock_instance( configSMP_SPINLOCK_0 ), pdTRUE ) - #define portRELEASE_ISR_LOCK() vPortRecursiveLock( 0, spin_lock_instance( configSMP_SPINLOCK_0 ), pdFALSE ) - #define portGET_TASK_LOCK() vPortRecursiveLock( 1, spin_lock_instance( configSMP_SPINLOCK_1 ), pdTRUE ) - #define portRELEASE_TASK_LOCK() vPortRecursiveLock( 1, spin_lock_instance( configSMP_SPINLOCK_1 ), pdFALSE ) + #define portGET_ISR_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), 0, spin_lock_instance( configSMP_SPINLOCK_0 ), pdTRUE ) + #define portRELEASE_ISR_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), 0, spin_lock_instance( configSMP_SPINLOCK_0 ), pdFALSE ) + #define portGET_TASK_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), 1, spin_lock_instance( configSMP_SPINLOCK_1 ), pdTRUE ) + #define portRELEASE_TASK_LOCK( xCoreID ) vPortRecursiveLock( ( xCoreID ), 1, spin_lock_instance( configSMP_SPINLOCK_1 ), pdFALSE ) #endif /*-----------------------------------------------------------*/ @@ -278,7 +275,7 @@ static inline void vPortRecursiveLock( uint32_t ulLockNum, #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) -#define portNOP() +#define portNOP() __asm volatile ( "nop" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) diff --git a/portable/ThirdParty/GCC/RP2040/include/rp2040_config.h b/portable/ThirdParty/GCC/RP2040/include/rp2040_config.h index a0f65c761..b2159a94e 100644 --- a/portable/ThirdParty/GCC/RP2040/include/rp2040_config.h +++ b/portable/ThirdParty/GCC/RP2040/include/rp2040_config.h @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: MIT AND BSD-3-Clause diff --git a/portable/ThirdParty/GCC/RP2040/library.cmake b/portable/ThirdParty/GCC/RP2040/library.cmake index 1db96517a..33968de85 100644 --- a/portable/ThirdParty/GCC/RP2040/library.cmake +++ b/portable/ThirdParty/GCC/RP2040/library.cmake @@ -46,9 +46,9 @@ target_compile_definitions(FreeRTOS-Kernel INTERFACE add_library(FreeRTOS-Kernel-Static INTERFACE) target_compile_definitions(FreeRTOS-Kernel-Static INTERFACE configSUPPORT_STATIC_ALLOCATION=1 + configKERNEL_PROVIDED_STATIC_MEMORY=1 ) -target_sources(FreeRTOS-Kernel-Static INTERFACE ${CMAKE_CURRENT_LIST_DIR}/idle_task_static_memory.c) target_link_libraries(FreeRTOS-Kernel-Static INTERFACE FreeRTOS-Kernel) add_library(FreeRTOS-Kernel-Heap1 INTERFACE) diff --git a/portable/ThirdParty/GCC/RP2040/port.c b/portable/ThirdParty/GCC/RP2040/port.c index d022ca2fa..66d633720 100644 --- a/portable/ThirdParty/GCC/RP2040/port.c +++ b/portable/ThirdParty/GCC/RP2040/port.c @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: MIT AND BSD-3-Clause @@ -46,9 +46,6 @@ #include "pico/multicore.h" #endif /* LIB_PICO_MULTICORE */ -/* TODO : consider to remove this macro. */ -#define portRUNNING_ON_BOTH_CORES ( configNUMBER_OF_CORES == portMAX_CORE_COUNT ) - /* Constants required to manipulate the NVIC. */ #define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) #define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) @@ -123,22 +120,21 @@ UBaseType_t uxCriticalNestings[ configNUMBER_OF_CORES ] = { 0 }; /*-----------------------------------------------------------*/ +#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 || configNUMBER_OF_CORES > 1 ) + #include "hardware/irq.h" +#endif /* ( configSUPPORT_PICO_SYNC_INTEROP == 1 || configNUMBER_OF_CORES > 1 ) */ #if ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) #include "pico/lock_core.h" - #include "hardware/irq.h" #include "event_groups.h" #if configSUPPORT_STATIC_ALLOCATION static StaticEventGroup_t xStaticEventGroup; #define pEventGroup ( &xStaticEventGroup ) #endif /* configSUPPORT_STATIC_ALLOCATION */ static EventGroupHandle_t xEventGroup; - #if ( portRUNNING_ON_BOTH_CORES == 0 ) + #if ( configNUMBER_OF_CORES == 1 ) static EventBits_t uxCrossCoreEventBits; - static spin_lock_t * pxCrossCoreSpinLock; + static spin_lock_t * pxCrossCoreSpinLock; /* protects uxCrossCoreEventBits */ #endif - - static spin_lock_t * pxYieldSpinLock[ configNUMBER_OF_CORES ]; - static uint32_t ulYieldSpinLockSaveValue[ configNUMBER_OF_CORES ]; #endif /* configSUPPORT_PICO_SYNC_INTEROP */ /* @@ -171,7 +167,7 @@ UBaseType_t uxCriticalNestings[ configNUMBER_OF_CORES ] = { 0 }; static uint8_t ucPrimaryCoreNum = INVALID_PRIMARY_CORE_NUM; /* Note: portIS_FREE_RTOS_CORE() also returns false until the scheduler is started */ -#if ( portRUNNING_ON_BOTH_CORES == 1 ) +#if ( configNUMBER_OF_CORES != 1 ) #define portIS_FREE_RTOS_CORE() ( ucPrimaryCoreNum != INVALID_PRIMARY_CORE_NUM ) #else #define portIS_FREE_RTOS_CORE() ( ucPrimaryCoreNum == get_core_num() ) @@ -247,35 +243,28 @@ void vPortStartFirstTask( void ) " ldr r0, [r0] \n" " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ #endif /* configRESET_STACK_POINTER */ - #if portRUNNING_ON_BOTH_CORES " adr r1, ulAsmLocals \n" /* Get the location of the current TCB for the current core. */ " ldmia r1!, {r2, r3} \n" " ldr r2, [r2] \n" /* r2 = Core number */ " lsls r2, #2 \n" " ldr r3, [r3, r2] \n" /* r3 = pxCurrentTCBs[get_core_num()] */ - #else - " ldr r3, =pxCurrentTCBs \n" - " ldr r3, [r3] \n" /* r3 = pxCurrentTCBs[0] */ - #endif /* portRUNNING_ON_BOTH_CORES */ - " ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ - " adds r0, #32 \n" /* Discard everything up to r0. */ - " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ - " movs r0, #2 \n" /* Switch to the psp stack. */ - " msr CONTROL, r0 \n" - " isb \n" - " pop {r0-r5} \n" /* Pop the registers that are saved automatically. */ - " mov lr, r5 \n" /* lr is now in r5. */ - " pop {r3} \n" /* Return address is now in r3. */ - " pop {r2} \n" /* Pop and discard XPSR. */ - " cpsie i \n" /* The first task has its context and interrupts can be enabled. */ - " bx r3 \n" /* Finally, jump to the user defined task code. */ - #if portRUNNING_ON_BOTH_CORES + " ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " adds r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " movs r0, #2 \n" /* Switch to the psp stack. */ + " msr CONTROL, r0 \n" + " isb \n" + " pop {r0-r5} \n" /* Pop the registers that are saved automatically. */ + " mov lr, r5 \n" /* lr is now in r5. */ + " pop {r3} \n" /* Return address is now in r3. */ + " pop {r2} \n" /* Pop and discard XPSR. */ + " cpsie i \n" /* The first task has its context and interrupts can be enabled. */ + " bx r3 \n" /* Finally, jump to the user defined task code. */ " \n" " .align 4 \n" "ulAsmLocals: \n" " .word 0xD0000000 \n" /* SIO */ " .word pxCurrentTCBs \n" - #endif /* portRUNNING_ON_BOTH_CORES */ ); #endif /* if ( configNUMBER_OF_CORES == 1 ) */ } @@ -291,7 +280,7 @@ void vPortStartFirstTask( void ) /* And explicitly clear any other IRQ flags. */ multicore_fifo_clear_irq(); - #if ( portRUNNING_ON_BOTH_CORES == 1 ) + #if ( configNUMBER_OF_CORES != 1 ) portYIELD_FROM_ISR( pdTRUE ); #elif ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) BaseType_t xHigherPriorityTaskWoken = pdFALSE; @@ -301,7 +290,7 @@ void vPortStartFirstTask( void ) spin_unlock( pxCrossCoreSpinLock, ulSave ); xEventGroupSetBitsFromISR( xEventGroup, ulBits, &xHigherPriorityTaskWoken ); portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); - #endif /* portRUNNING_ON_BOTH_CORES */ + #endif /* configNUMBER_OF_CORES != 1 */ } #endif /* if ( LIB_PICO_MULTICORE == 1 ) && ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) */ @@ -346,23 +335,21 @@ void vPortStartFirstTask( void ) /* Should never get here as the tasks will now be executing! Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this - * functionality by defining configTASK_RETURN_ADDRESS. Call - * vTaskSwitchContext() so link time optimisation does not remove the + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext( portGET_CORE_ID() ); prvTaskExitError(); - /* Should not get here! */ + /* Should not get here. */ return 0; } - #if portRUNNING_ON_BOTH_CORES - static void prvDisableInterruptsAndPortStartSchedulerOnCore( void ) - { - portDISABLE_INTERRUPTS(); - xPortStartSchedulerOnCore(); - } - #endif + static void prvDisableInterruptsAndPortStartSchedulerOnCore( void ) + { + portDISABLE_INTERRUPTS(); + xPortStartSchedulerOnCore(); + } /* * See header file for description. @@ -375,13 +362,11 @@ void vPortStartFirstTask( void ) spin_lock_claim( configSMP_SPINLOCK_0 ); spin_lock_claim( configSMP_SPINLOCK_1 ); - #if portRUNNING_ON_BOTH_CORES - ucPrimaryCoreNum = configTICK_CORE; - configASSERT( get_core_num() == 0 ); /* we must be started on core 0 */ - multicore_launch_core1( prvDisableInterruptsAndPortStartSchedulerOnCore ); - #else - ucPrimaryCoreNum = get_core_num(); - #endif + ucPrimaryCoreNum = configTICK_CORE; + configASSERT( get_core_num() == 0 ); /* we must be started on core 0 */ + multicore_reset_core1(); + multicore_launch_core1( prvDisableInterruptsAndPortStartSchedulerOnCore ); + xPortStartSchedulerOnCore(); /* Should not get here! */ @@ -417,7 +402,7 @@ void vPortStartFirstTask( void ) #if ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) multicore_fifo_clear_irq(); multicore_fifo_drain(); - uint32_t irq_num = 15 + get_core_num(); + uint32_t irq_num = SIO_IRQ_PROC0 + get_core_num(); irq_set_priority( irq_num, portMIN_INTERRUPT_PRIORITY ); irq_set_exclusive_handler( irq_num, prvFIFOInterruptHandler ); irq_set_enabled( irq_num, 1 ); @@ -430,8 +415,8 @@ void vPortStartFirstTask( void ) /* Should never get here as the tasks will now be executing! Call the task * exit error function to prevent compiler warnings about a static function * not being called in the case that the application writer overrides this - * functionality by defining configTASK_RETURN_ADDRESS. Call - * vTaskSwitchContext() so link time optimisation does not remove the + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimization does not remove the * symbol. */ vTaskSwitchContext(); prvTaskExitError(); @@ -445,20 +430,14 @@ void vPortStartFirstTask( void ) void vPortEndScheduler( void ) { - /* Not implemented in ports where there is nothing to return to. */ - panic_unsupported(); + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( portGET_CORE_ID() == 1000UL ); } /*-----------------------------------------------------------*/ void vPortYield( void ) { - #if ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) - - /* We are not in an ISR, and pxYieldSpinLock is always dealt with and - * cleared when interrupts are re-enabled, so should be NULL */ - configASSERT( pxYieldSpinLock[ portGET_CORE_ID() ] == NULL ); - #endif /* configSUPPORT_PICO_SYNC_INTEROP */ - /* Set a PendSV to request a context switch. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; @@ -494,21 +473,6 @@ void vPortYield( void ) } #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ -void vPortEnableInterrupts( void ) -{ - #if ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) - int xCoreID = ( int ) portGET_CORE_ID(); - - if( pxYieldSpinLock[ xCoreID ] ) - { - spin_lock_t * const pxTmpLock = pxYieldSpinLock[ xCoreID ]; - pxYieldSpinLock[ xCoreID ] = NULL; - spin_unlock( pxTmpLock, ulYieldSpinLockSaveValue[ xCoreID ] ); - } - #endif - __asm volatile ( " cpsie i " ::: "memory" ); -} - /*-----------------------------------------------------------*/ uint32_t ulSetInterruptMaskFromISR( void ) @@ -541,7 +505,7 @@ void vYieldCore( int xCoreID ) configASSERT( xCoreID != ( int ) portGET_CORE_ID() ); - #if portRUNNING_ON_BOTH_CORES + #if configNUMBER_OF_CORES != 1 /* Non blocking, will cause interrupt on other core if the queue isn't already full, * in which case an IRQ must be pending */ @@ -644,13 +608,9 @@ void xPortPendSVHandler( void ) " \n" " adr r0, ulAsmLocals2 \n" /* Get the location of the current TCB for the current core. */ " ldmia r0!, {r2, r3} \n" - #if portRUNNING_ON_BOTH_CORES - " ldr r0, [r2] \n" /* r0 = Core number */ - " lsls r0, r0, #2 \n" - " adds r3, r0 \n" /* r3 = &pxCurrentTCBs[get_core_num()] */ - #else - " \n" /* r3 = &pxCurrentTCBs[0] */ - #endif /* portRUNNING_ON_BOTH_CORES */ + " ldr r0, [r2] \n" /* r0 = Core number */ + " lsls r0, r0, #2 \n" + " adds r3, r0 \n" /* r3 = &pxCurrentTCBs[get_core_num()] */ " ldr r0, [r3] \n" /* r0 = pxCurrentTCB */ " \n" " subs r1, r1, #32 \n" /* Make space for the remaining low registers. */ @@ -684,11 +644,7 @@ void xPortPendSVHandler( void ) " subs r1, r1, #48 \n" " stmia r1!, {r4-r7} \n" #endif /* portUSE_DIVIDER_SAVE_RESTORE */ - #if portRUNNING_ON_BOTH_CORES - " ldr r0, [r2] \n" /* r0 = Core number */ - #else - " movs r0, #0 \n" - #endif /* portRUNNING_ON_BOTH_CORES */ + " ldr r0, [r2] \n" /* r0 = Core number */ " push {r3, r14} \n" " cpsid i \n" " bl vTaskSwitchContext \n" @@ -1000,10 +956,10 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) ulBit = 1u << ( spin_lock_get_num( spinLock ) & 0x7u ); #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - ulBit = 1u << spin_lock_get_num( spinLock ); - /* reduce to range 0-24 */ - ulBit |= ulBit << 8u; - ulBit >>= 8u; + /* Avoid potential use of SIO divider for % here out of abundance of caution */ + ulBit = spin_lock_get_num( spinLock ); + if (ulBit >= 24) ulBit -= 24; + ulBit = 1u << ulBit; #endif /* configTICK_TYPE_WIDTH_IN_BITS */ return ( EventBits_t ) ulBit; } @@ -1021,8 +977,8 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) uint32_t ulSave ) { configASSERT( !portCHECK_IF_IN_ISR() ); + configASSERT( pxLock->spin_lock ); - /* note no need to check LIB_PICO_MULTICORE, as this is always returns true if that is not defined */ if( !portIS_FREE_RTOS_CORE() ) { spin_unlock( pxLock->spin_lock, ulSave ); @@ -1030,15 +986,43 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) } else { - configASSERT( pxYieldSpinLock[ portGET_CORE_ID() ] == NULL ); - - /* we want to hold the lock until the event bits have been set; since interrupts are currently disabled */ - /* by the spinlock, we can defer until portENABLE_INTERRUPTS is called which is always called when */ - /* the scheduler is unlocked during this call */ - configASSERT( pxLock->spin_lock ); - int xCoreID = ( int ) portGET_CORE_ID(); - pxYieldSpinLock[ xCoreID ] = pxLock->spin_lock; - ulYieldSpinLockSaveValue[ xCoreID ] = ulSave; + /* The requirement (from the SDK) on this implementation is that this method + * should always wake up from a corresponding call to vPortLockInternalSpinUnlockWithNotify + * that happens after this method is called. + * + * The moment that we unlock the spin lock, we need to be sure that + * there is no way that we end up blocking in xEventGroupWaitBits, + * despite the fact that other tasks can now run, if the corresponding + * unlock has occurred. + * + * Previously the RP2xxx ports used to attempt to disable IRQs until the + * task actually (potentially) became blocked by hooking the IRQ re-enable + * when xEventGroupWaitBits completes (or switches tasks), but this + * was a broken hack, in that IRQs are re-enabled at other points during + * that call. + * + * This deferred IRQ enable is not actually needed, because all we + * care about is that: + * + * Even in the presence of other tasks acquiring then releasing + * the lock, between the interrupt_enable and the xEventGroupWaitBits, + * the corresponding bit will still be set. + * + * This is the case, even any intervening blocked lock (which + * clears the event bit) will need to unlock it before we proceed, + * which will set the event bit again. + * + * The multiplexing down of multiple spin lock numbers to fewer + * event bits does not cause a possible race condition, + * but it does mean that a task waiting for lock A can be + * blocked by a task B which owns another lock. + * + * This could be fixed by using an array of event groups, however + * since the SDK spin locks are generally intended for very short + * term usage anyway, and rarely nested except in exotic cases + * like video output, we'll leave it as one event group for now + */ + spin_unlock( pxLock->spin_lock, ulSave); xEventGroupWaitBits( xEventGroup, prvGetEventGroupBit( pxLock->spin_lock ), pdTRUE, pdFALSE, portMAX_DELAY ); } @@ -1071,11 +1055,7 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) else { __sev(); - #if ( portRUNNING_ON_BOTH_CORES == 0 ) - - /* We could sent the bits across the FIFO which would have required us to block here if the FIFO was full, - * or we could have just set all bits on the other side, however it seems reasonable instead to take - * the hit of another spin lock to protect an accurate bit set. */ + #if ( configNUMBER_OF_CORES == 1 ) if( pxCrossCoreSpinLock != pxLock->spin_lock ) { spin_lock_unsafe_blocking( pxCrossCoreSpinLock ); @@ -1089,7 +1069,7 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* This causes fifo irq on the other (FreeRTOS) core which will do the set the event bits */ sio_hw->fifo_wr = 0; - #endif /* portRUNNING_ON_BOTH_CORES == 0 */ + #endif /* configNUMBER_OF_CORES == 1 */ spin_unlock( pxLock->spin_lock, ulSave ); } } @@ -1099,6 +1079,7 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) absolute_time_t uxUntil ) { configASSERT( !portCHECK_IF_IN_ISR() ); + configASSERT( pxLock->spin_lock ); /* note no need to check LIB_PICO_MULTICORE, as this is always returns true if that is not defined */ if( !portIS_FREE_RTOS_CORE() ) @@ -1109,19 +1090,14 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) else { configASSERT( portIS_FREE_RTOS_CORE() ); - configASSERT( pxYieldSpinLock[ portGET_CORE_ID() ] == NULL ); TickType_t uxTicksToWait = prvGetTicksToWaitBefore( uxUntil ); if( uxTicksToWait ) { - /* We want to hold the lock until the event bits have been set; since interrupts are currently disabled - * by the spinlock, we can defer until portENABLE_INTERRUPTS is called which is always called when - * the scheduler is unlocked during this call */ - configASSERT( pxLock->spin_lock ); - int xCoreID = ( int ) portGET_CORE_ID(); - pxYieldSpinLock[ xCoreID ] = pxLock->spin_lock; - ulYieldSpinLockSaveValue[ xCoreID ] = ulSave; + /* See comment in vPortLockInternalSpinUnlockWithWait for detail + * about possible race conditions */ + spin_unlock( pxLock->spin_lock, ulSave ); xEventGroupWaitBits( xEventGroup, prvGetEventGroupBit( pxLock->spin_lock ), pdTRUE, pdFALSE, uxTicksToWait ); @@ -1151,9 +1127,9 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) { /* This must be done even before the scheduler is started, as the spin lock * is used by the overrides of the SDK wait/notify primitives */ - #if ( portRUNNING_ON_BOTH_CORES == 0 ) + #if ( configNUMBER_OF_CORES == 1 ) pxCrossCoreSpinLock = spin_lock_instance( next_striped_spin_lock_num() ); - #endif /* portRUNNING_ON_BOTH_CORES */ + #endif /* configNUMBER_OF_CORES == 1 */ /* The event group is not used prior to scheduler init, but is initialized * here to since it logically belongs with the spin lock */ diff --git a/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h b/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h index 111c99f1a..57f7b0156 100644 --- a/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h +++ b/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h @@ -7,8 +7,8 @@ */ /* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -85,7 +85,7 @@ /* If CONFIG_FREERTOS_ASSERT_DISABLE is set then configASSERT is defined empty later in FreeRTOS.h and the macro */ /* configASSERT_DEFINED remains unset (meaning some warnings are avoided) */ -#ifdef configASSERT +#if ( configASSERT_DEFINED == 1 ) #undef configASSERT #if defined( CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE ) #define configASSERT( a ) \ @@ -114,7 +114,7 @@ * interrupts. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY XCHAL_EXCM_LEVEL -/* Stack alignment, architecture specifc. Must be a power of two. */ +/* Stack alignment, architecture specific. Must be a power of two. */ #define configSTACK_ALIGNMENT 16 diff --git a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h index c5981eaa5..2f3fe55e0 100644 --- a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h +++ b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h @@ -8,8 +8,8 @@ */ /* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -522,7 +522,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t usStackDepth ) PRIVILEGED_FUNCTION; + configSTACK_DEPTH_TYPE uxStackDepth ) PRIVILEGED_FUNCTION; void vPortReleaseTaskMPUSettings( xMPU_SETTINGS * xMPUSettings ); #endif diff --git a/portable/ThirdParty/GCC/Xtensa_ESP32/port.c b/portable/ThirdParty/GCC/Xtensa_ESP32/port.c index 49139d71d..a89868baa 100644 --- a/portable/ThirdParty/GCC/Xtensa_ESP32/port.c +++ b/portable/ThirdParty/GCC/Xtensa_ESP32/port.c @@ -8,8 +8,8 @@ */ /* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -308,10 +308,10 @@ void vPortYieldOtherCore( BaseType_t coreid ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t usStackDepth ) + configSTACK_DEPTH_TYPE uxStackDepth ) { #if XCHAL_CP_NUM > 0 - xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + usStackDepth - 1 ) ); + xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + uxStackDepth - 1 ) ); xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) xMPUSettings->coproc_area ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( uint32_t ) xMPUSettings->coproc_area - XT_CP_SIZE ) & ~0xf ); diff --git a/portable/ThirdParty/Partner-Supported-Ports b/portable/ThirdParty/Partner-Supported-Ports index da0185fbf..abc22103e 160000 --- a/portable/ThirdParty/Partner-Supported-Ports +++ b/portable/ThirdParty/Partner-Supported-Ports @@ -1 +1 @@ -Subproject commit da0185fbf1215706af66d020a67edf912193979a +Subproject commit abc22103e1e6634b33457d4127bff1ab62f27f90 diff --git a/portable/ThirdParty/XCC/Xtensa/Makefile b/portable/ThirdParty/XCC/Xtensa/Makefile deleted file mode 100644 index 909cbd2c2..000000000 --- a/portable/ThirdParty/XCC/Xtensa/Makefile +++ /dev/null @@ -1,97 +0,0 @@ -### Makefile to build the FreeRTOS library ### - -# Build target (options: sim, board) - -TARGET = sim -SMALL = - -# Tools - -CC = xt-xcc -AS = xt-xcc -AR = xt-ar -XT_CORE = $(patsubst %-params,%,$(notdir $(shell xt-xcc --show-config=core))) -CONFIGDIR = $(shell xt-xcc --show-config=config) - -# For platform-specific commands - -include $(CONFIGDIR)/misc/hostenv.mk - -# Source code and build locations - -SRCROOT = $(subst /,$(S),$(CURDIR)) -TSTROOT = $(abspath $(SRCROOT)$(S)..$(S)..$(S)..$(S)..$(S)..$(S)demos$(S)cadence$(S)sim$(SMALL)) -BLDROOT = $(TSTROOT)$(S)build -BLDDIR = $(BLDROOT)$(S)$(XT_CORE) - -FR_SRCDIR = $(abspath $(SRCROOT)$(S)..$(S)..$(S)..) -FR_SRCDIR2 = $(FR_SRCDIR)$(S)portable$(S)MemMang -XT_SRCDIR = $(SRCROOT) - -vpath %.c $(FR_SRCDIR) $(FR_SRCDIR2) $(XT_SRCDIR) -vpath %.S $(XT_SRCDIR) - -# File lists - -FR_C_FILES = $(notdir $(wildcard $(FR_SRCDIR)/*.c)) $(notdir $(wildcard $(FR_SRCDIR2)/*.c)) -XT_C_FILES = $(notdir $(wildcard $(XT_SRCDIR)/*.c)) -XT_S_FILES = $(notdir $(wildcard $(XT_SRCDIR)/*.S)) - -# List of all .o files that will go into the library - -LIB_C_O = $(patsubst %.c,%.o,$(XT_C_FILES) $(FR_C_FILES)) -LIB_S_O = $(patsubst %.S,%.o,$(XT_S_FILES)) -LIB_O_LIST = $(addprefix $(BLDDIR)/,$(LIB_C_O) $(LIB_S_O)) - -# Output files - -OSLIB = $(BLDDIR)$(S)libfreertos.a - -# Build options - -ifeq ($(TARGET),sim) -DFLAGS = -DXT_SIMULATOR -endif -ifeq ($(TARGET),board) -DFLAGS = -DXT_BOARD -endif - -IFLAGS = \ - -I$(FR_SRCDIR)$(S)..$(S)include -I$(FR_SRCDIR)$(S)..$(S)include$(S)private \ - -I$(XT_SRCDIR) -I$(TSTROOT)$(S)common$(S)config_files -I$(BLDDIR) - -CFLAGS = -O2 -g -CCFLAGS = $(CFLAGS) -Wall -mno-coproc -mlongcalls -ffunction-sections -mno-l32r-flix $(DFLAGS) -ASFLAGS = $(CCFLAGS) - -# Include dependency rules (generated using -MD) - --include $(wildcard $(BLDDIR)/*.d) - -# Targets - -all : mkdir $(OSLIB) - -mkdir : $(BLDDIR)/.mkdir - -$(BLDDIR)/.mkdir : - @$(MKPATH) $(BLDDIR) - @echo "" > $@ - -$(CP) $(CONFIGDIR)/xtensa-elf/include/sys/reent.h $(BLDDIR)/reent.h - -$(OSLIB) : $(LIB_O_LIST) - $(AR) -rs $@ $^ - -$(BLDDIR)/%.o : %.c - $(CC) $(CCFLAGS) $(IFLAGS) -MD -MF $(subst .o,.d,$@) -c -o $@ $< - -$(BLDDIR)/%.o : %.S - $(CC) $(ASFLAGS) $(IFLAGS) -MD -MF $(subst .o,.d,$@) -c -o $@ $< - -clean : - $(RM_R) $(BLDDIR) - -clean_all : - $(RM_R) $(BLDROOT) - -.PHONY : all mkdir clean clean_all diff --git a/portable/ThirdParty/XCC/Xtensa/port.c b/portable/ThirdParty/XCC/Xtensa/port.c deleted file mode 100644 index a95784167..000000000 --- a/portable/ThirdParty/XCC/Xtensa/port.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#include -#include - -#include "xtensa_rtos.h" - -#include "FreeRTOS.h" -#include "task.h" - - -/* Defined in portasm.h */ -extern void _frxt_tick_timer_init( void ); - -/* Defined in xtensa_context.S */ -extern void _xt_coproc_init( void ); - - -/*-----------------------------------------------------------*/ - -/* We require the address of the pxCurrentTCB variable, but don't want to know - * any details of its type. */ -typedef void TCB_t; -extern volatile TCB_t * volatile pxCurrentTCB; - -unsigned port_xSchedulerRunning = 0; /* Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting */ -unsigned port_interruptNesting = 0; /* Interrupt nesting level */ - -/*-----------------------------------------------------------*/ - -/* User exception dispatcher when exiting */ -void _xt_user_exit( void ); - -/* - * Stack initialization - */ -#if portUSING_MPU_WRAPPERS - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters ) -#endif -{ - StackType_t * sp; - StackType_t * tp; - XtExcFrame * frame; - - #if XCHAL_CP_NUM > 0 - uint32_t * p; - #endif - - /* Create interrupt stack frame aligned to 16 byte boundary */ - sp = ( StackType_t * ) ( ( ( UBaseType_t ) pxTopOfStack - XT_CP_SIZE - XT_STK_FRMSZ ) & ~0xf ); - - /* Clear the entire frame (do not use memset() because we don't depend on C library) */ - for( tp = sp; tp <= pxTopOfStack; ++tp ) - { - *tp = 0; - } - - frame = ( XtExcFrame * ) sp; - - /* Explicitly initialize certain saved registers */ - frame->pc = ( UBaseType_t ) pxCode; /* task entrypoint */ - frame->a0 = 0; /* to terminate GDB backtrace */ - frame->a1 = ( UBaseType_t ) sp + XT_STK_FRMSZ; /* physical top of stack frame */ - frame->exit = ( UBaseType_t ) _xt_user_exit; /* user exception exit dispatcher */ - - /* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */ - /* Also set entry point argument parameter. */ - #ifdef __XTENSA_CALL0_ABI__ - frame->a2 = ( UBaseType_t ) pvParameters; - frame->ps = PS_UM | PS_EXCM; - #else - /* + for windowed ABI also set WOE and CALLINC (pretend task was 'call4'd). */ - frame->a6 = ( UBaseType_t ) pvParameters; - frame->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC( 1 ); - #endif - - #ifdef XT_USE_SWPRI - /* Set the initial virtual priority mask value to all 1's. */ - frame->vpri = 0xFFFFFFFF; - #endif - - #if XCHAL_CP_NUM > 0 - /* Init the coprocessor save area (see xtensa_context.h) */ - - /* No access to TCB here, so derive indirectly. Stack growth is top to bottom. - * //p = (uint32_t *) xMPUSettings->coproc_area; - */ - p = ( uint32_t * ) ( ( ( uint32_t ) pxTopOfStack - XT_CP_SIZE ) & ~0xf ); - configASSERT( ( uint32_t ) p >= frame->a1 ); - p[ 0 ] = 0; - p[ 1 ] = 0; - p[ 2 ] = ( ( ( uint32_t ) p ) + 12 + XCHAL_TOTAL_SA_ALIGN - 1 ) & -XCHAL_TOTAL_SA_ALIGN; - #endif - - return sp; -} - -/*-----------------------------------------------------------*/ - -void vPortEndScheduler( void ) -{ - /* It is unlikely that the Xtensa port will get stopped. If required simply - * disable the tick interrupt here. */ -} - -/*-----------------------------------------------------------*/ - -BaseType_t xPortStartScheduler( void ) -{ - /* Interrupts are disabled at this point and stack contains PS with enabled interrupts when task context is restored */ - - #if XCHAL_CP_NUM > 0 - /* Initialize co-processor management for tasks. Leave CPENABLE alone. */ - _xt_coproc_init(); - #endif - - /* Init the tick divisor value */ - _xt_tick_divisor_init(); - - /* Setup the hardware to generate the tick. */ - _frxt_tick_timer_init(); - - #if XT_USE_THREAD_SAFE_CLIB - /* Init C library */ - vPortClibInit(); - #endif - - port_xSchedulerRunning = 1; - - /* Cannot be directly called from C; never returns */ - __asm__ volatile ( "call0 _frxt_dispatch\n" ); - - /* Should not get here. */ - return pdTRUE; -} -/*-----------------------------------------------------------*/ - -BaseType_t xPortSysTickHandler( void ) -{ - BaseType_t ret; - uint32_t interruptMask; - - portbenchmarkIntLatency(); - - /* Interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY must be - * disabled before calling xTaskIncrementTick as it access the - * kernel lists. */ - interruptMask = portSET_INTERRUPT_MASK_FROM_ISR(); - { - ret = xTaskIncrementTick(); - } - portCLEAR_INTERRUPT_MASK_FROM_ISR( interruptMask ); - - portYIELD_FROM_ISR( ret ); - - return ret; -} -/*-----------------------------------------------------------*/ - -/* - * Used to set coprocessor area in stack. Current hack is to reuse MPU pointer for coprocessor area. - */ -#if portUSING_MPU_WRAPPERS - void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, - const struct xMEMORY_REGION * const xRegions, - StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) - { - #if XCHAL_CP_NUM > 0 - xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + ulStackDepth - 1 ) ); - xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) xMPUSettings->coproc_area ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); - xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( uint32_t ) xMPUSettings->coproc_area - XT_CP_SIZE ) & ~0xf ); - - /* NOTE: we cannot initialize the coprocessor save area here because FreeRTOS is going to - * clear the stack area after we return. This is done in pxPortInitialiseStack(). - */ - #endif - } -#endif /* if portUSING_MPU_WRAPPERS */ diff --git a/portable/ThirdParty/XCC/Xtensa/portasm.S b/portable/ThirdParty/XCC/Xtensa/portasm.S deleted file mode 100644 index 10754ecad..000000000 --- a/portable/ThirdParty/XCC/Xtensa/portasm.S +++ /dev/null @@ -1,600 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#include "xtensa_rtos.h" - -#define TOPOFSTACK_OFFS 0x00 /* StackType_t *pxTopOfStack */ -#define CP_TOPOFSTACK_OFFS 0x04 /* xMPU_SETTINGS.coproc_area */ - -.extern pxCurrentTCB - - -/* -******************************************************************************* -* Interrupt stack. The size of the interrupt stack is determined by the config -* parameter "configISR_STACK_SIZE" in FreeRTOSConfig.h -******************************************************************************* -*/ - .data - .align 16 - .global port_IntStack -port_IntStack: - .space configISR_STACK_SIZE -port_IntStackTop: - .word 0 -port_switch_flag: - .word 0 - - .text -/* -******************************************************************************* -* _frxt_setup_switch -* void _frxt_setup_switch(void); -* -* Sets an internal flag indicating that a task switch is required on return -* from interrupt handling. -* -******************************************************************************* -*/ - .global _frxt_setup_switch - .type _frxt_setup_switch,@function - .align 4 -_frxt_setup_switch: - - ENTRY(16) - - movi a2, port_switch_flag - movi a3, 1 - s32i a3, a2, 0 - - RET(16) - -/* -******************************************************************************* -* _frxt_int_enter -* void _frxt_int_enter(void) -* -* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_ENTER function for -* freeRTOS. Saves the rest of the interrupt context (not already saved). -* May only be called from assembly code by the 'call0' instruction, with -* interrupts disabled. -* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h. -* -******************************************************************************* -*/ - .globl _frxt_int_enter - .type _frxt_int_enter,@function - .align 4 -_frxt_int_enter: - - /* Save a12-13 in the stack frame as required by _xt_context_save. */ - s32i a12, a1, XT_STK_A12 - s32i a13, a1, XT_STK_A13 - - /* Save return address in a safe place (free a0). */ - mov a12, a0 - - /* Save the rest of the interrupted context (preserves A12-13). */ - call0 _xt_context_save - - /* - Save interrupted task's SP in TCB only if not nesting. - Manage nesting directly rather than call the generic IntEnter() - (in windowed ABI we can't call a C function here anyway because PS.EXCM is still set). - */ - movi a2, port_xSchedulerRunning - movi a3, port_interruptNesting - l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */ - beqz a2, 1f /* scheduler not running, no tasks */ - l32i a2, a3, 0 /* a2 = port_interruptNesting */ - addi a2, a2, 1 /* increment nesting count */ - s32i a2, a3, 0 /* save nesting count */ - bnei a2, 1, .Lnested /* !=0 before incr, so nested */ - - movi a2, pxCurrentTCB - l32i a2, a2, 0 /* a2 = current TCB */ - beqz a2, 1f - s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */ - movi a1, port_IntStackTop /* a1 = top of intr stack */ - -.Lnested: -1: - mov a0, a12 /* restore return addr and return */ - ret - -/* -******************************************************************************* -* _frxt_int_exit -* void _frxt_int_exit(void) -* -* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_EXIT function for -* FreeRTOS. If required, calls vPortYieldFromInt() to perform task context -* switching, restore the (possibly) new task's context, and return to the -* exit dispatcher saved in the task's stack frame at XT_STK_EXIT. -* May only be called from assembly code by the 'call0' instruction. Does not -* return to caller. -* See the description of the XT_RTOS_ENTER macro in xtensa_rtos.h. -* -******************************************************************************* -*/ - .globl _frxt_int_exit - .type _frxt_int_exit,@function - .align 4 -_frxt_int_exit: - - movi a2, port_xSchedulerRunning - movi a3, port_interruptNesting - rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */ - l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */ - beqz a2, .Lnoswitch /* scheduler not running, no tasks */ - l32i a2, a3, 0 /* a2 = port_interruptNesting */ - addi a2, a2, -1 /* decrement nesting count */ - s32i a2, a3, 0 /* save nesting count */ - bnez a2, .Lnesting /* !=0 after decr so still nested */ - - movi a2, pxCurrentTCB - l32i a2, a2, 0 /* a2 = current TCB */ - beqz a2, 1f /* no task ? go to dispatcher */ - l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */ - - movi a2, port_switch_flag /* address of switch flag */ - l32i a3, a2, 0 /* a3 = port_switch_flag */ - beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */ - movi a3, 0 - s32i a3, a2, 0 /* zero out the flag for next time */ - -1: - /* - Call0 ABI callee-saved regs a12-15 need to be saved before possible preemption. - However a12-13 were already saved by _frxt_int_enter(). - */ - #ifdef __XTENSA_CALL0_ABI__ - s32i a14, a1, XT_STK_A14 - s32i a15, a1, XT_STK_A15 - #endif - - #ifdef __XTENSA_CALL0_ABI__ - call0 vPortYieldFromInt /* call dispatch inside the function; never returns */ - #else - call4 vPortYieldFromInt /* this one returns */ - call0 _frxt_dispatch /* tail-call dispatcher */ - /* Never returns here. */ - #endif - -.Lnoswitch: - /* - If we came here then about to resume the interrupted task. - */ - -.Lnesting: - /* - We come here only if there was no context switch, that is if this - is a nested interrupt, or the interrupted task was not preempted. - In either case there's no need to load the SP. - */ - - /* Restore full context from interrupt stack frame */ - call0 _xt_context_restore - - /* - Must return via the exit dispatcher corresponding to the entrypoint from which - this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt - stack frame is deallocated in the exit dispatcher. - */ - l32i a0, a1, XT_STK_EXIT - ret - - -/* -********************************************************************************************************** -* _frxt_timer_int -* void _frxt_timer_int(void) -* -* Implements the Xtensa RTOS porting layer's XT_RTOS_TIMER_INT function for FreeRTOS. -* Called every timer interrupt. -* Manages the tick timer and calls xPortSysTickHandler() every tick. -* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h. -* -* Callable from C (obeys ABI conventions). Implemented in assmebly code for performance. -* -********************************************************************************************************** -*/ - .globl _frxt_timer_int - .type _frxt_timer_int,@function - .align 4 -_frxt_timer_int: - - /* - Xtensa timers work by comparing a cycle counter with a preset value. Once the match occurs - an interrupt is generated, and the handler has to set a new cycle count into the comparator. - To avoid clock drift due to interrupt latency, the new cycle count is computed from the old, - not the time the interrupt was serviced. However if a timer interrupt is ever serviced more - than one tick late, it is necessary to process multiple ticks until the new cycle count is - in the future, otherwise the next timer interrupt would not occur until after the cycle - counter had wrapped (2^32 cycles later). - - do { - ticks++; - old_ccompare = read_ccompare_i(); - write_ccompare_i( old_ccompare + divisor ); - service one tick; - diff = read_ccount() - old_ccompare; - } while ( diff > divisor ); - */ - - ENTRY(16) - -.L_xt_timer_int_catchup: - - /* Update the timer comparator for the next tick. */ - #ifdef XT_CLOCK_FREQ - movi a2, XT_TICK_DIVISOR /* a2 = comparator increment */ - #else - movi a3, _xt_tick_divisor - l32i a2, a3, 0 /* a2 = comparator increment */ - #endif - rsr a3, XT_CCOMPARE /* a3 = old comparator value */ - add a4, a3, a2 /* a4 = new comparator value */ - wsr a4, XT_CCOMPARE /* update comp. and clear interrupt */ - esync - - #ifdef __XTENSA_CALL0_ABI__ - /* Preserve a2 and a3 across C calls. */ - s32i a2, sp, 4 - s32i a3, sp, 8 - #endif - - /* Call the FreeRTOS tick handler (see port.c). */ - #ifdef __XTENSA_CALL0_ABI__ - call0 xPortSysTickHandler - #else - call4 xPortSysTickHandler - #endif - - #ifdef __XTENSA_CALL0_ABI__ - /* Restore a2 and a3. */ - l32i a2, sp, 4 - l32i a3, sp, 8 - #endif - - /* Check if we need to process more ticks to catch up. */ - esync /* ensure comparator update complete */ - rsr a4, CCOUNT /* a4 = cycle count */ - sub a4, a4, a3 /* diff = ccount - old comparator */ - blt a2, a4, .L_xt_timer_int_catchup /* repeat while diff > divisor */ - - RET(16) - - /* -********************************************************************************************************** -* _frxt_tick_timer_init -* void _frxt_tick_timer_init(void) -* -* Initialize timer and timer interrrupt handler (_xt_tick_divisor_init() has already been been called). -* Callable from C (obeys ABI conventions on entry). -* -********************************************************************************************************** -*/ - .globl _frxt_tick_timer_init - .type _frxt_tick_timer_init,@function - .align 4 -_frxt_tick_timer_init: - - ENTRY(16) - - /* Set up the periodic tick timer (assume enough time to complete init). */ - #ifdef XT_CLOCK_FREQ - movi a3, XT_TICK_DIVISOR - #else - movi a2, _xt_tick_divisor - l32i a3, a2, 0 - #endif - rsr a2, CCOUNT /* current cycle count */ - add a2, a2, a3 /* time of first timer interrupt */ - wsr a2, XT_CCOMPARE /* set the comparator */ - - /* - Enable the timer interrupt at the device level. Don't write directly - to the INTENABLE register because it may be virtualized. - */ - #ifdef __XTENSA_CALL0_ABI__ - movi a2, XT_TIMER_INTEN - call0 xt_ints_on - #else - movi a6, XT_TIMER_INTEN - call4 xt_ints_on - #endif - - RET(16) - -/* -********************************************************************************************************** -* DISPATCH THE HIGH READY TASK -* void _frxt_dispatch(void) -* -* Switch context to the highest priority ready task, restore its state and dispatch control to it. -* -* This is a common dispatcher that acts as a shared exit path for all the context switch functions -* including vPortYield() and vPortYieldFromInt(), all of which tail-call this dispatcher -* (for windowed ABI vPortYieldFromInt() calls it indirectly via _frxt_int_exit() ). -* -* The Xtensa port uses different stack frames for solicited and unsolicited task suspension (see -* comments on stack frames in xtensa_context.h). This function restores the state accordingly. -* If restoring a task that solicited entry, restores the minimal state and leaves CPENABLE clear. -* If restoring a task that was preempted, restores all state including the task's CPENABLE. -* -* Entry: -* pxCurrentTCB points to the TCB of the task to suspend, -* Because it is tail-called without a true function entrypoint, it needs no 'entry' instruction. -* -* Exit: -* If incoming task called vPortYield() (solicited), this function returns as if from vPortYield(). -* If incoming task was preempted by an interrupt, this function jumps to exit dispatcher. -* -********************************************************************************************************** -*/ - .globl _frxt_dispatch - .type _frxt_dispatch,@function - .align 4 -_frxt_dispatch: - - #ifdef __XTENSA_CALL0_ABI__ - call0 vTaskSwitchContext // Get next TCB to resume - movi a2, pxCurrentTCB - #else - movi a2, pxCurrentTCB - call4 vTaskSwitchContext // Get next TCB to resume - #endif - l32i a3, a2, 0 - l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */ - s32i a3, a2, 0 - - /* Determine the type of stack frame. */ - l32i a2, sp, XT_STK_EXIT /* exit dispatcher or solicited flag */ - bnez a2, .L_frxt_dispatch_stk - -.L_frxt_dispatch_sol: - - /* Solicited stack frame. Restore minimal context and return from vPortYield(). */ - l32i a3, sp, XT_SOL_PS - #ifdef __XTENSA_CALL0_ABI__ - l32i a12, sp, XT_SOL_A12 - l32i a13, sp, XT_SOL_A13 - l32i a14, sp, XT_SOL_A14 - l32i a15, sp, XT_SOL_A15 - #endif - l32i a0, sp, XT_SOL_PC - #if XCHAL_CP_NUM > 0 - /* Ensure wsr.CPENABLE is complete (should be, it was cleared on entry). */ - rsync - #endif - /* As soons as PS is restored, interrupts can happen. No need to sync PS. */ - wsr a3, PS - #ifdef __XTENSA_CALL0_ABI__ - addi sp, sp, XT_SOL_FRMSZ - ret - #else - retw - #endif - -.L_frxt_dispatch_stk: - - #if XCHAL_CP_NUM > 0 - /* Restore CPENABLE from task's co-processor save area. */ - movi a3, pxCurrentTCB /* cp_state = */ - l32i a3, a3, 0 - l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */ - l16ui a3, a2, XT_CPENABLE /* CPENABLE = cp_state->cpenable; */ - wsr a3, CPENABLE - #endif - - /* Interrupt stack frame. Restore full context and return to exit dispatcher. */ - call0 _xt_context_restore - - /* In Call0 ABI, restore callee-saved regs (A12, A13 already restored). */ - #ifdef __XTENSA_CALL0_ABI__ - l32i a14, sp, XT_STK_A14 - l32i a15, sp, XT_STK_A15 - #endif - - #if XCHAL_CP_NUM > 0 - /* Ensure wsr.CPENABLE has completed. */ - rsync - #endif - - /* - Must return via the exit dispatcher corresponding to the entrypoint from which - this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt - stack frame is deallocated in the exit dispatcher. - */ - l32i a0, sp, XT_STK_EXIT - ret - - -/* -********************************************************************************************************** -* PERFORM A SOLICTED CONTEXT SWITCH (from a task) -* void vPortYield(void) -* -* This function saves the minimal state needed for a solicited task suspension, clears CPENABLE, -* then tail-calls the dispatcher _frxt_dispatch() to perform the actual context switch -* -* At Entry: -* pxCurrentTCB points to the TCB of the task to suspend -* Callable from C (obeys ABI conventions on entry). -* -* Does not return to caller. -* -********************************************************************************************************** -*/ - .globl vPortYield - .type vPortYield,@function - .align 4 -vPortYield: - - #ifdef __XTENSA_CALL0_ABI__ - addi sp, sp, -XT_SOL_FRMSZ - #else - entry sp, XT_SOL_FRMSZ - #endif - - rsr a2, PS - s32i a0, sp, XT_SOL_PC - s32i a2, sp, XT_SOL_PS - #ifdef __XTENSA_CALL0_ABI__ - s32i a12, sp, XT_SOL_A12 /* save callee-saved registers */ - s32i a13, sp, XT_SOL_A13 - s32i a14, sp, XT_SOL_A14 - s32i a15, sp, XT_SOL_A15 - #else - /* Spill register windows. Calling xthal_window_spill() causes extra */ - /* spills and reloads, so we will set things up to call the _nw version */ - /* instead to save cycles. */ - movi a6, ~(PS_WOE_MASK|PS_INTLEVEL_MASK) /* spills a4-a7 if needed */ - and a2, a2, a6 /* clear WOE, INTLEVEL */ - addi a2, a2, XCHAL_EXCM_LEVEL /* set INTLEVEL */ - wsr a2, PS - rsync - call0 xthal_window_spill_nw - l32i a2, sp, XT_SOL_PS /* restore PS */ - wsr a2, PS - #endif - - rsil a2, XCHAL_EXCM_LEVEL /* disable low/med interrupts */ - - #if XCHAL_CP_NUM > 0 - /* Save coprocessor callee-saved state (if any). At this point CPENABLE */ - /* should still reflect which CPs were in use (enabled). */ - call0 _xt_coproc_savecs - #endif - - movi a2, pxCurrentTCB - movi a3, 0 - l32i a2, a2, 0 /* a2 = pxCurrentTCB */ - s32i a3, sp, XT_SOL_EXIT /* 0 to flag as solicited frame */ - s32i sp, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */ - - #if XCHAL_CP_NUM > 0 - /* Clear CPENABLE, also in task's co-processor state save area. */ - l32i a2, a2, CP_TOPOFSTACK_OFFS /* a2 = pxCurrentTCB->cp_state */ - movi a3, 0 - wsr a3, CPENABLE - beqz a2, 1f - s16i a3, a2, XT_CPENABLE /* clear saved cpenable */ -1: - #endif - - /* Tail-call dispatcher. */ - call0 _frxt_dispatch - /* Never reaches here. */ - - -/* -********************************************************************************************************** -* PERFORM AN UNSOLICITED CONTEXT SWITCH (from an interrupt) -* void vPortYieldFromInt(void) -* -* This calls the context switch hook (removed), saves and clears CPENABLE, then tail-calls the dispatcher -* _frxt_dispatch() to perform the actual context switch. -* -* At Entry: -* Interrupted task context has been saved in an interrupt stack frame at pxCurrentTCB->pxTopOfStack. -* pxCurrentTCB points to the TCB of the task to suspend, -* Callable from C (obeys ABI conventions on entry). -* -* At Exit: -* Windowed ABI defers the actual context switch until the stack is unwound to interrupt entry. -* Call0 ABI tail-calls the dispatcher directly (no need to unwind) so does not return to caller. -* -********************************************************************************************************** -*/ - .globl vPortYieldFromInt - .type vPortYieldFromInt,@function - .align 4 -vPortYieldFromInt: - - ENTRY(16) - - #if XCHAL_CP_NUM > 0 - /* Save CPENABLE in task's co-processor save area, and clear CPENABLE. */ - movi a3, pxCurrentTCB /* cp_state = */ - l32i a3, a3, 0 - l32i a2, a3, CP_TOPOFSTACK_OFFS - - rsr a3, CPENABLE - s16i a3, a2, XT_CPENABLE /* cp_state->cpenable = CPENABLE; */ - movi a3, 0 - wsr a3, CPENABLE /* disable all co-processors */ - #endif - - #ifdef __XTENSA_CALL0_ABI__ - /* Tail-call dispatcher. */ - call0 _frxt_dispatch - /* Never reaches here. */ - #else - RET(16) - #endif - -/* -********************************************************************************************************** -* _frxt_task_coproc_state -* void _frxt_task_coproc_state(void) -* -* Implements the Xtensa RTOS porting layer's XT_RTOS_CP_STATE function for FreeRTOS. -* -* May only be called when a task is running, not within an interrupt handler (returns 0 in that case). -* May only be called from assembly code by the 'call0' instruction. Does NOT obey ABI conventions. -* Returns in A15 a pointer to the base of the co-processor state save area for the current task. -* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h. -* -********************************************************************************************************** -*/ -#if XCHAL_CP_NUM > 0 - - .globl _frxt_task_coproc_state - .type _frxt_task_coproc_state,@function - .align 4 -_frxt_task_coproc_state: - - movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */ - l32i a15, a15, 0 - beqz a15, 1f - movi a15, port_interruptNesting /* && port_interruptNesting == 0 */ - l32i a15, a15, 0 - bnez a15, 1f - movi a15, pxCurrentTCB - l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */ - beqz a15, 2f - l32i a15, a15, CP_TOPOFSTACK_OFFS - ret - -1: movi a15, 0 -2: ret - -#endif /* XCHAL_CP_NUM > 0 */ diff --git a/portable/ThirdParty/XCC/Xtensa/portbenchmark.h b/portable/ThirdParty/XCC/Xtensa/portbenchmark.h deleted file mode 100644 index deb1cd0d6..000000000 --- a/portable/ThirdParty/XCC/Xtensa/portbenchmark.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * This utility helps benchmarking interrupt latency and context switches. - * In order to enable it, set configBENCHMARK to 1 in FreeRTOSConfig.h. - * You will also need to download the FreeRTOS_trace patch that contains - * portbenchmark.c and the complete version of portbenchmark.h - */ - -#ifndef PORTBENCHMARK_H -#define PORTBENCHMARK_H - -#if configBENCHMARK - #error "You need to download the FreeRTOS_trace patch that overwrites this file" -#endif - -#define portbenchmarkINTERRUPT_DISABLE() -#define portbenchmarkINTERRUPT_RESTORE( newstate ) -#define portbenchmarkIntLatency() -#define portbenchmarkIntWait() -#define portbenchmarkReset() -#define portbenchmarkPrint() - -#endif /* PORTBENCHMARK */ diff --git a/portable/ThirdParty/XCC/Xtensa/portclib.c b/portable/ThirdParty/XCC/Xtensa/portclib.c deleted file mode 100644 index bb415fbbe..000000000 --- a/portable/ThirdParty/XCC/Xtensa/portclib.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#include "FreeRTOS.h" - -#if XT_USE_THREAD_SAFE_CLIB - - #if XSHAL_CLIB == XTHAL_CLIB_XCLIB - - #include - #include - - #include "semphr.h" - - typedef SemaphoreHandle_t _Rmtx; - -/*----------------------------------------------------------------------------- */ -/* Override this and set to nonzero to enable locking. */ -/*----------------------------------------------------------------------------- */ - int32_t _xclib_use_mt = 1; - - -/*----------------------------------------------------------------------------- */ -/* Init lock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxinit( _Rmtx * mtx ) - { - *mtx = xSemaphoreCreateRecursiveMutex(); - } - -/*----------------------------------------------------------------------------- */ -/* Destroy lock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxdst( _Rmtx * mtx ) - { - if( ( mtx != NULL ) && ( *mtx != NULL ) ) - { - vSemaphoreDelete( *mtx ); - } - } - -/*----------------------------------------------------------------------------- */ -/* Lock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxlock( _Rmtx * mtx ) - { - if( ( mtx != NULL ) && ( *mtx != NULL ) ) - { - xSemaphoreTakeRecursive( *mtx, portMAX_DELAY ); - } - } - -/*----------------------------------------------------------------------------- */ -/* Unlock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxunlock( _Rmtx * mtx ) - { - if( ( mtx != NULL ) && ( *mtx != NULL ) ) - { - xSemaphoreGiveRecursive( *mtx ); - } - } - -/*----------------------------------------------------------------------------- */ -/* Called by malloc() to allocate blocks of memory from the heap. */ -/*----------------------------------------------------------------------------- */ - void * _sbrk_r( struct _reent * reent, - int32_t incr ) - { - extern char _end; - extern char _heap_sentry; - static char * _heap_sentry_ptr = &_heap_sentry; - static char * heap_ptr; - char * base; - - if( !heap_ptr ) - { - heap_ptr = ( char * ) &_end; - } - - base = heap_ptr; - - if( heap_ptr + incr >= _heap_sentry_ptr ) - { - reent->_errno = ENOMEM; - return ( char * ) -1; - } - - heap_ptr += incr; - return base; - } - -/*----------------------------------------------------------------------------- */ -/* Global initialization for C library. */ -/*----------------------------------------------------------------------------- */ - void vPortClibInit( void ) - { - } - -/*----------------------------------------------------------------------------- */ -/* Per-thread cleanup stub provided for linking, does nothing. */ -/*----------------------------------------------------------------------------- */ - void _reclaim_reent( void * ptr ) - { - } - - #endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */ - - #if XSHAL_CLIB == XTHAL_CLIB_NEWLIB - - #include - #include - #include - #include - #include - - #include "semphr.h" - - static SemaphoreHandle_t xClibMutex; - static uint32_t ulClibInitDone = 0; - -/*----------------------------------------------------------------------------- */ -/* Get C library lock. */ -/*----------------------------------------------------------------------------- */ - void __malloc_lock( struct _reent * ptr ) - { - if( !ulClibInitDone ) - { - return; - } - - xSemaphoreTakeRecursive( xClibMutex, portMAX_DELAY ); - } - -/*----------------------------------------------------------------------------- */ -/* Release C library lock. */ -/*----------------------------------------------------------------------------- */ - void __malloc_unlock( struct _reent * ptr ) - { - if( !ulClibInitDone ) - { - return; - } - - xSemaphoreGiveRecursive( xClibMutex ); - } - -/*----------------------------------------------------------------------------- */ -/* Lock for environment. Since we have only one global lock we can just call */ -/* the malloc() lock function. */ -/*----------------------------------------------------------------------------- */ - void __env_lock( struct _reent * ptr ) - { - __malloc_lock( ptr ); - } - - -/*----------------------------------------------------------------------------- */ -/* Unlock environment. */ -/*----------------------------------------------------------------------------- */ - void __env_unlock( struct _reent * ptr ) - { - __malloc_unlock( ptr ); - } - -/*----------------------------------------------------------------------------- */ -/* Called by malloc() to allocate blocks of memory from the heap. */ -/*----------------------------------------------------------------------------- */ - void * _sbrk_r( struct _reent * reent, - int32_t incr ) - { - extern char _end; - extern char _heap_sentry; - static char * _heap_sentry_ptr = &_heap_sentry; - static char * heap_ptr; - char * base; - - if( !heap_ptr ) - { - heap_ptr = ( char * ) &_end; - } - - base = heap_ptr; - - if( heap_ptr + incr >= _heap_sentry_ptr ) - { - reent->_errno = ENOMEM; - return ( char * ) -1; - } - - heap_ptr += incr; - return base; - } - -/*----------------------------------------------------------------------------- */ -/* Global initialization for C library. */ -/*----------------------------------------------------------------------------- */ - void vPortClibInit( void ) - { - configASSERT( !ulClibInitDone ); - - xClibMutex = xSemaphoreCreateRecursiveMutex(); - ulClibInitDone = 1; - } - - #endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */ - -#endif /* XT_USE_THREAD_SAFE_CLIB */ diff --git a/portable/ThirdParty/XCC/Xtensa/portmacro.h b/portable/ThirdParty/XCC/Xtensa/portmacro.h deleted file mode 100644 index 21d3e5384..000000000 --- a/portable/ThirdParty/XCC/Xtensa/portmacro.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef PORTMACRO_H -#define PORTMACRO_H - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -#ifndef __ASSEMBLER__ - - #include - - #include - #include - #include - #include /* required for XSHAL_CLIB */ - #include - -/*#include "xtensa_context.h" */ - -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ - -/* Type definitions. */ - - #define portCHAR int8_t - #define portFLOAT float - #define portDOUBLE double - #define portLONG int32_t - #define portSHORT int16_t - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE int - - typedef portSTACK_TYPE StackType_t; - typedef portBASE_TYPE BaseType_t; - typedef unsigned portBASE_TYPE UBaseType_t; - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif -/*-----------------------------------------------------------*/ - -/* portbenchmark */ - #include "portbenchmark.h" - -/* Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? */ -/* These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. */ - #define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL( XCHAL_EXCM_LEVEL ); portbenchmarkINTERRUPT_DISABLE(); } while( 0 ) - #define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE( 0 ); XTOS_SET_INTLEVEL( 0 ); } while( 0 ) - -/* These can be nested */ - #define portCRITICAL_NESTING_IN_TCB 1 /* For now, let FreeRTOS' (tasks.c) manage critical nesting */ - void vTaskEnterCritical( void ); - void vTaskExitCritical( void ); - #define portENTER_CRITICAL() vTaskEnterCritical() - #define portEXIT_CRITICAL() vTaskExitCritical() - -/* Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack. */ -/* They can be called from interrupts too. */ - static inline unsigned portENTER_CRITICAL_NESTED() - { - unsigned state = XTOS_SET_INTLEVEL( XCHAL_EXCM_LEVEL ); - - portbenchmarkINTERRUPT_DISABLE(); - return state; - } - #define portEXIT_CRITICAL_NESTED( state ) do { portbenchmarkINTERRUPT_RESTORE( state ); XTOS_RESTORE_JUST_INTLEVEL( state ); } while( 0 ) - -/* These FreeRTOS versions are similar to the nested versions above */ - #define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( state ) portEXIT_CRITICAL_NESTED( state ) - -/*-----------------------------------------------------------*/ - -/* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 4 - #define portNOP() XT_NOP() -/*-----------------------------------------------------------*/ - -/* Fine resolution time */ - #define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount() - -/* Kernel utilities. */ - void vPortYield( void ); - void _frxt_setup_switch( void ); - #define portYIELD() vPortYield() - #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) \ - if( ( xHigherPriorityTaskWoken ) != 0 ) { \ - _frxt_setup_switch(); \ - } - -/*-----------------------------------------------------------*/ - -/* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - -/* When coprocessors are defined, we to maintain a pointer to coprocessors area. */ -/* We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: */ -/* MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. */ -/* The field is normally used for memory protection. FreeRTOS should create another general purpose field. */ - typedef struct - { - #if XCHAL_CP_NUM > 0 - volatile StackType_t * coproc_area; /* Pointer to coprocessor save area; MUST BE FIRST */ - #endif - - #if portUSING_MPU_WRAPPERS - /* Define here mpu_settings, which is port dependent */ - int mpu_setting; /* Just a dummy example here; MPU not ported to Xtensa yet */ - #endif - - #if configUSE_TRACE_FACILITY_2 - struct - { - /* Cf. porttraceStamp() */ - int taskstamp; /* Stamp from inside task to see where we are */ - int taskstampcount; /* A counter usually incremented when we restart the task's loop */ - } porttrace; - #endif - } xMPU_SETTINGS; - -/* Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS) */ - #if ( XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2 ) && !portUSING_MPU_WRAPPERS /* If MPU wrappers not used, we still need to allocate coproc area */ - #undef portUSING_MPU_WRAPPERS - #define portUSING_MPU_WRAPPERS 1 /* Enable it to allocate coproc area */ - #define MPU_WRAPPERS_H /* Override mpu_wrapper.h to disable unwanted code */ - #define PRIVILEGED_FUNCTION - #define PRIVILEGED_DATA - #endif - -/* porttrace */ - #if configUSE_TRACE_FACILITY_2 - #include "porttrace.h" - #endif - -/* configASSERT_2 if requested */ - #if configASSERT_2 - #include - void exit( int ); - #define configASSERT( x ) if( !( x ) ) { porttracePrint( -1 ); printf( "\nAssertion failed in %s:%d\n", __FILE__, __LINE__ ); exit( -1 ); } - #endif - - -/* C library support -- only XCLIB and NEWLIB are supported. */ - -/* To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must be - * defined to be > 0 somewhere above or on the command line. */ - - #if ( XT_USE_THREAD_SAFE_CLIB > 0u ) && ( XSHAL_CLIB == XTHAL_CLIB_XCLIB ) - extern void vPortClibInit( void ); - #endif // XCLIB support - - #if ( XT_USE_THREAD_SAFE_CLIB > 0u ) && ( XSHAL_CLIB == XTHAL_CLIB_NEWLIB ) - extern void vPortClibInit( void ); - -/* This C library cleanup is not currently done by FreeRTOS when deleting a task */ - #include - #define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTcbClib( &( ( pxTCB )->xNewLib_reent ) ) - static inline void vPortCleanUpTcbClib( struct _reent * ptr ) - { - FILE * fp = &( ptr->__sf[ 0 ] ); - int i; - - for( i = 0; i < 3; ++i, ++fp ) - { - fp->_close = NULL; - } - } - #endif // NEWLIB support - -#endif // __ASSEMBLER__ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* PORTMACRO_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/porttrace.h b/portable/ThirdParty/XCC/Xtensa/porttrace.h deleted file mode 100644 index 7a2ad1d53..000000000 --- a/portable/ThirdParty/XCC/Xtensa/porttrace.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * This utility helps tracing the entering and exiting from tasks. - * It maintains a circular buffer of tasks in the order they execute, - * and their execution time. To enable it, set configUSE_TRACE_FACILITY_2 - * to 1 in FreeRTOSConfig.h. You will also need to download the - * FreeRTOS_trace patch that contains porttrace.c and the complete version - * of porttrace.h. - */ - -#ifndef PORTTRACE_H -#define PORTTRACE_H - -#if configUSE_TRACE_FACILITY_2 - #error "You need to download the FreeRTOS_trace patch that overwrites this file" -#endif - -#define porttracePrint( nelements ) -#define porttraceStamp( stamp, count_incr ) - -#endif /* PORTTRACE_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/readme_xtensa.txt b/portable/ThirdParty/XCC/Xtensa/readme_xtensa.txt index 56dcc6965..e2ee4307c 100644 --- a/portable/ThirdParty/XCC/Xtensa/readme_xtensa.txt +++ b/portable/ThirdParty/XCC/Xtensa/readme_xtensa.txt @@ -1,763 +1,11 @@ - FreeRTOS Port for Xtensa Configurable and Diamond Processors - ============================================================ + FreeRTOS Port for Xtensa Configurable Processors + ================================================ - FreeRTOS Kernel Version 10.0.0 +The Xtensa FreeRTOS port has moved and can be found in the +"FreeRTOS-Kernel-Partner-Supported-Ports" submodule of FreeRTOS-Kernel: +FreeRTOS/Source/portable/ThirdParty/Partner-Supported-Ports/Cadence/Xtensa -Introduction ------------- - -This document describes the Xtensa port for FreeRTOS multitasking RTOS. -For an introduction to FreeRTOS itself, please refer to FreeRTOS -documentation. - -This port currently works with FreeRTOS kernel version 10.0.0. - - -Xtensa Configuration Requirements and Restrictions --------------------------------------------------- - -The Xtensa configurable architecture supports a vast space of processor -features. This port supports all of them, including custom processor -extensions defined in the TIE language, with certain minimum -requirements. You must use Xtensa Tools to compile and link FreeRTOS and -your application for your Xtensa configuration. The port uses the Xtensa -Hardware Abstraction Layer (HAL) to adapt to your Xtensa configuration. -NOTE: It may be possible to build and run this with the open-source -xtensa-linux tools provided you have the correct overlay for your Xtensa -configuration. However, this has not been tested and is currently not -supported by Cadence. - -This port includes optional reentrancy support for the 'newlib' and -'xclib' C runtime libraries distributed with Xtensa Tools, providing -thread-safety on a per task basis (for use in tasks only, not interrupt -handlers). - -NOTE: At this time only 'newlib' and 'xclib' C libraries are supported -for thread safety. The 'uclibc' library is not reentrant and does not -provide thread safety at this time. However, if you are not concerned -with reentrancy then you can use any of these libraries. - -This port also includes a simple example application that may run on -a supported board or the Xtensa instruction set simulator (ISS). There -are also a couple of test programs used in maintaining the port, which -serve as additional examples. - -FreeRTOS for Xtensa configurable processors requires the following minimum -processor configuration options: -- Timer interrupt option with at least one interruptible timer. -- Interrupt option (implied by the timer interrupt option). -- Exception Architecture 2 (XEA2). Please note that XEA1 is NOT supported. - All 'Diamond', 'Xtensa 6', 'Xtensa LX' and 'Xtensa LX2' processors and - most 'Xtensa T1050' processors are configured with XEA2. -All Diamond processor cores meet these requirements and are supported. - -Minimal support for certain evaluation boards is provided via a board -independent XTBSP API implemented by a board specific library distributed -with the Xtensa Tools. This provides the board clock frequency and basic -polled drivers for the display and console device. Note that XTBSP -is not a tradtional RTOS "board support package" with RTOS specific -interrupt-driven drivers - it is not specific to any RTOS. Note that -FreeRTOS can run on any Xtensa or Diamond board without this board support -(a "raw" platform), but you will have to provide the clock frequency -and drivers for any on-board devices you want to use. - - -Installation ------------- - -The Xtensa port of FreeRTOS is available at this location: - - https://github.com/foss-xtensa/amazon-freertos - -This download includes the core FreeRTOS source and include files needed -to build the port. You can also download the official release of FreeRTOS -version 1.0.0 or later from this location: - - https://github.com/aws/amazon-freertos - -The Xtensa port files are currently not included in the official package. - -All source is provided along with a Makefile that works for any host -platform supported by Xtensa Tools (Windows, Linux). These instructions -are written for Windows users, but can easily be understood and adapted -to other host platforms. - -First install the FreeRTOS common package in a directory of your choosing. -The structure of that package will look like this: - - -|-- demos -| `-- cadence -| `-- sim -| |-- common -| | |-- application_code -| | | `-- cadence_code -| | `-- config_files -| `-- xplorer -`-- lib - |-- FreeRTOS - | `-- portable - | |-- Common - | |-- MemMang - | `-- XCC - | `-- Xtensa - `-- include - `-- private - -The Xtensa Tools are available from Cadence as part of a processor -license. Be sure you have installed the Xtensa Tools and your processor -configuration. - - -Building FreeRTOS for Xtensa ----------------------------- - -To build the FreeRTOS library and the example programs, go into the -directory 'demos/cadence/sim' and use the makefile in that directory. -"make all" will build all the examples. There is another makefile in -the 'lib/FreeRTOS/portable/XCC/Xtensa' directory that builds just the -FreeRTOS library. - -By default, you will build for the Xtensa instruction set simulator. If -you have a supported emulation board, you can build to run on that. You -can also build to run on a raw Xtensa core with no board support, a -good starting point for supporting your own target platform. Cadence -recommends doing functional development on the simulator because it -is easier to debug with, then move to a board if/when you need to test -hardware drivers or real-time performance. - -The provided makefile simplifies building FreeRTOS and the example -for your Xtensa configuration and platform (ISS, board, etc.). There -are detailed instructions in the comments at the top of the makefile. - -The makefiles work on Windows and Linux and support incremental builds. -The build for each Xtensa configuration and target platform is placed in -a subdirectory so several core and platform builds can co-exist even with -incremental rebuilds. You may specify the root of the build area (if tou -want it to be elsewhere than under the source tree) by defining BLDROOT -either in the make command or your shell environment. - - -Building the FreeRTOS Library ------------------------------ - -First, be sure you have installed Xtensa Tools and your processor -configuration, and be sure that Xtensa Tools are in your search path. -You can use xt-make, which comes with the Xtensa Tools, to run the -makefiles. - -Change directories to the Xtensa port directory: - -> cd lib/FreeRTOS/portable/XCC/Xtensa - -Now build the FreeRTOS RTOS as a library (libfreertos.a) as follows: - -> xt-make - -which by default builds for the simulator (TARGET=sim), or: - -> xt-make TARGET=board - -which builds for a supported board. Note that the board type does not -need to be specified when building the FreeRTOS library. - -If you are building for an Xtensa processor configuration that is not the -default you selected when you installed Xtensa Tools, you need to define the -environment variable XTENSA_CORE. If your configuration is not in the -default registry you selected when you installed Xtensa Tools, you also -need to define the environment variable XTENSA_SYSTEM. See tools manuals. -You can avoid defining these in your environment if you pass the variables -you need to redefine into xt-make as follows: - -> xt-make XTENSA_CORE= XTENSA_SYSTEM= ... - -There are more details about build options in the comment in the Makefile. - -After the library has been built, you must link your application with this -library in order to use FreeRTOS. - - -Building the FreeRTOS Examples ------------------------------- - -The provided examples are designed to run on the Xtensa instruction set -simulator (ISS) or a supported evaluation board programmed with your -Xtensa processor configuration. - -To build the examples for the default platform (simulator): - -> cd demos/cadence/sim - -> xt-make all - -which is the same as - -> xt-make all TARGET=sim - -The boards currently supported are the Xilinx ML605 and KC705 FPGA -development boards. To target these boards, type - -> xt-make all TARGET=ml605 - -or - -> xt-make all TARGET=kc705 - -To build in a location other than the default, specify the new location -using the BLDROOT variable. Note that this makefile will invoke the -FreeRTOS library build makefile automatically, passing on the relevant -parameters based on what you specified. - -You can override the default compilation options by specifying the new -options via CFLAGS. For example: - -> xt-make all TARGET=sim CFLAGS="-O2 -Os -g" - -This compiles the examples and links them with the FreeRTOS library -libfreertos.a and the appropriate linker-support package (LSP) for your -target platform (you can override the LSP by adding LSP= to the -xt-make command line). The resulting ELF files can be downloaded and -executed on the target. The example binaries appear in the platform -specific subdirectory described earlier. - -To build your application with thread-safe C library support, you -need to make certain modifications to the application to plug in and -invoke the reentrancy support. This allows each task to use the library -without interference with other tasks (it is not safe for interrupt -handlers to call the C library). - -First, you must define - - XT_USE_THREAD_SAFE_CLIB - -to a nonzero value either in xtensa_config.h or on the compiler's command -line. Note that the default xtensa_config.h provided with this port does -define this to 1 if either newlib or xclib is detected. - -Then, you must also make sure to allocate extra space on the stack for -each task that will use the C library reentrant functions. This extra -space is to be allocated over and above the actual stack space required -by the task itself. The define - - XT_STACK_EXTRA_CLIB - -specifies the amount of extra space to be added on to the stack to allow -saving the context for the C library as well as the coprocessors if any. -E.g. if your task requires 2000 bytes of stack space, you must allocate -(2000 + XT_STACK_EXTRA_CLIB) bytes for the stack. - - -IMPORTANT NOTE --------------- - -The header file FreeRTOS.h, which is a part of the core FreeRTOS sources, -includes if thread safety for the C libraries is enabled. For -xclib, this file exists in and so is reported as missing. -To work around this, the makefiles supplied with this port will copy the -reent.h header into the build directory during the build process. If you -use a different build process, then you must make sure to copy this file -to a location that is included in the list of include paths. This can be -the build directory or the directory that contains the Xtensa port source -files. - - -Running or Debugging an Application ------------------------------------ - -To execute the example application on the simulator: - -> xt-run [--turbo] example.exe - -The option --turbo provides much faster, but non-cycle-accurate simulation -(the --turbo option is only available with Xtensa Tools version 7 or later). - - -To execute on the simulator using the Xplorer GUI based debugger: - -> xplorer --debug example.exe - - -To execute on a supported evaluation board, download example.exe per -instructions in the tools manuals. Be sure the board has been programmed -with the correct configuration and is set up to boot from RAM and debug -a downloaded program! Optionally you may connect a terminal or terminal -emulator to the serial port on the board with settings as described in -the board user manual, and see the output of printf on the terminal. - -To obtain I/O on a "raw" platform such as an unsupported board, you need -to provide low level I/O drivers (eg. inbyte() and outbyte() for character -I/O if you want to use printf etc.). You can run "raw" executables on -any Xtensa platform, including simulator and any board, but you will not -see any behavior specific to the platform (eg. display, printed output, -stopping simulation at end of program). You can, while debugging, use a -debugger mechanism called GDBIO to obtain basic I/O. To use GDBIO, link -with the gdbio LSP. Refer to Xtensa tools documentation for details. - - -Task Stack Sizes ----------------- - -The application must ensure that every task has enough space for its -stack. Each task needs enough space for its own use, its own interrupt -stack frame (defined in xtensa_context.h) and space to save coprocessor -state, if any. Several factors influence the size of the stack required, -including the compiler optimization level and the use of the C library. -Calls to standard output functions such as printf() can use up a lot of -stack space. The tool xt-stack-usage is helpful in determining safe stack -sizes for your application. - -Some macros are provided in xtensa_config.h to help determine the stack -size for tasks that do and do not use the C library. Use these as the -basis for each task's stack size. They are minimum requirements taking -into account your configuration and use of the C library. In particular, -the define - - XT_STACK_MIN_SIZE - -defines the minimum stack size for any task. Be very careful if you try -to use a stack size smaller than this minimum. Stack overruns can cause -all kinds of hard-to-debug errors. It is recommended that you enable the -FreeRTOS stack checking features during development. - -WARNING: The newlib printf() function uses a lot of stack space. Be very -careful in using it. Optionally you can use the 'libxtutil' library for -output - it implements a subset of printf() that has smaller code size -and uses far less stack space. More information about this library is in -the Xtensa Tools documentation. - - -Interrupt Stack ---------------- - -Beginning with port version 1.2, the port uses a separate interrupt stack -for handling interrupts. Thus, it is no longer necessary for each task to -reserve space on its stack to handle interrupts. The size of the interrupt -stack is controlled by the parameter "configISR_STACK_SIZE" defined in -FreeRTOSConfig.h. Define this carefully to match your system requirements. - - -Assembler / Compiler Switches ------------------------------ - -The following are compiler switches are used by the provided -Makefile in building the FreeRTOS library and example application. -These can be modified by editing the Makefile or by overriding the -CFLAGS variable in the make command line, for example: - -> xt-make CFLAGS="-O2 -DXT_USE_THREAD_SAFE_CLIB" - - -g Specifies debug information. - -c Specifies object code generation. - -On Sets compiler optimization level n (default -O0). - -mlongcalls Allows assembler and linker to convert call - instructions to longer indirect call sequences - when target is out of range. - -x assembler-with-cpp Passes .s and .S files through C preprocessor. - -Dmacro Define a preprocessor macro with no value. - -Dmacro=value Define a preprocessor macro with a value. - -See the compiler / linker documentation for a full list of switches and -their use. - -Many definitions can be provided at compile-time via the -D option -without editing the source code. Here are some of the more useful ones: - - XT_USE_THREAD_SAFE_CLIB Enable support for the reentrancy to provide - thread-safety for the newlib and xclib libraries - supplied with Xtensa Tools. Default ON. - - Note, the follwing defines are unique to the Xtensa port so have names - beginning with "XT_". - - XT_SIMULATOR Set this if building to run on the simulator. - Takes advantage of certain simulator control - and reporting facilities, and adjusts timing - of periodic tick to provide a more acceptable - performance in simulation (see XT_CLOCK_FREQ). - Set by default unless PLATFORM is overridden. - - XT_BOARD Set this if building for a supported board. - Be sure to specify the correct LSP for the - board. See the example makefile for usage. - - XT_CLOCK_FREQ=freq Specifies the target processor's clock - frequency in Hz. Used primarily to set the - timer that generates the periodic interrupt. - Defaults are provided and may be edited in - xtensa_timer.h (see comments there also). - Default for simulator provides more acceptable - performance, but cannot provide real-time - performance due to variation in simulation - speed per host platform and insufficient - cycles between interrupts to process them. - Supported board platforms by default leave - this undefined and compute the clock frequency - at initialization unless this is explicitly - defined. - - XT_TICK_PER_SEC=n Specifies the frequency of the periodic tick. - - XT_TIMER_INDEX=n Specifies which timer to use for periodic tick. - Set this if your Xtensa processor configuration - provides more than one suitable timer and you - want to override the default. See xtensa_timer.h . - - XT_INTEXC_HOOKS Enables hooks in interrupt vector handlers - to support dynamic installation of exception - and interrupt handlers. Disabled by default. - - XT_USE_OVLY Enable code overlay support. It uses a mutex, - hence configUSE_MUTEX must be enabled. This - option is currently unsupported. - - XT_USE_SWPRI Enable software prioritization of interrupts. - Enabling this will prioritize interrupts with - higher bit numbers over those with lower bit - numbers at the same level. This works only for - low and medium priority interrupts that can be - dispatched to C handlers. - - -Register Usage and Stack Frames -------------------------------- - -The Xtensa architecture specifies two ABIs that determine how the general -purpose registers a0-a15 are used: the standard windowed ABI use with -the Xtensa windowed register file architecture, and the optional and -more conventional Call0 ABI (required for Xtensa configurations without -a windowed register file). - -Xtensa processors may have other special registers (including co-processor -registers and other TIE "states") that are independent of this choice -of ABI. See Xtensa documentation for more details. - -In the windowed ABI the registers of the current window are used as follows: - a0 = return address - a1 = stack pointer (alias sp) - a2 = first argument and result of call (in simple cases) - a3-7 = second through sixth arguments of call (in simple cases). - Note that complex or large arguments are passed on the - stack. Details are in the Xtensa Tools manuals. - a8-a15 = available for use as temporaries. -There are no callee-save registers. The windowed hardware automatically -saves registers a0-a3 on a call4, a0-a8 on a call8, a0-a12 on a call12, -by rotating the register window. Hardware triggers window overflow and -underflow exceptions as necessary when registers outside the current -window need to be spilled to preallocated space in the stack frame, or -restored. Complete details are in the Xtensa manuals. The entire windowed -register file is saved and restored on interrupt or task context switch. - -The Call0 ABI does not make use of register windows, relying instead -on a fixed set of 16 registers without window rotation. -The Call0 ABI is more conventional and uses registers as follows: - a0 = return address - a1 = stack pointer (alias sp) - a2 = first argument and result of call (in simple cases) - a3-7 = second through sixth arguments of call (in simple cases). - Note that complex or large arguments are passed on the - stack. Details are in the Xtensa Tools manuals. - a8-a11 = scratch. - a12-a15 = callee-save (a function must preserve these for its caller). -On a FreeRTOS API call, callee-save registers are saved only when a task -context switch occurs, and other registers are not saved at all (the caller -does not expect them to be preserved). On an interrupt, callee-saved -registers might only be saved and restored when a task context-switch -occurs, but all other registers are always saved and restored. - -An Xtensa processor has other special registers independent of the ABI, -depending on the configuration (including co-processor registers and other -TIE state) that are part of the task context. FreeRTOS preserves all such -registers over an unsolicited context-switch triggered by an interrupt. -However it does NOT preserve these over a solicited context-switch during -a FreeRTOS API call. This bears some explanation. These special registers -are either ignored by the compiler or treated as caller-saved, meaning -that if kept "live" over a function call (ie. need to be preserved) -they must be saved and restored by the caller. Since solicited entry to -FreeRTOS is always made by a function call, FreeRTOS assumes the caller -has saved any of these registers that are "live". FreeRTOS avoids a lot -of overhead by not having to save and restore every special register -(there can be many) on every solicited context switch. - -As a consequence, the application developer should NOT assume that special -registers are preserved over a FreeRTOS API call such as vTaskDelay(). -If multiple tasks use a register, the caller must save and restore it. - -The saved context stack frames for context switches that occur as -a result of interrupt handling (interrupt frame) or from task-level -API calls (solicited frame) are described in human readable form in -xtensa_context.h . All suspended tasks have one of these two types -of stack frames. The top of the suspended task's stack is pointed to -by pxCurrentTCB->pxTopOfStack. A special location common to both stack -frames differentiates solicited and interrupt stack frames. - - -Improving Performance, Footprint, or Ease of Debugging ------------------------------------------------------- - -By default FreeRTOS for Xtensa is built with debug (-g) and without -compiler optimizations (-O0). This makes debugging easier. Of course, --O0 costs performance and usually also increases stack usage. To make -FreeRTOS run faster you can change the Makefile to enable the desired -optimizations or set a predefined optimization level (-O) . - -Maximum performance is achieved with -O3 -ipa, but that might increase -the footprint substantially. A good compromise is -O2. See the compiler -manual for details. - -Minimal footprint is achieved by optimizing for space with -Os, at the -cost of some performance. See the compiler manual for details. - -The Xtensa architecture port-specific assembly files are coded with no -file-scope labels inside functions (all labels inside functions begin with -".L"). This allows a profiler to accurately associate an address with a -function, and also allows the debugger's stack trace to show the correct -function wherever the program counter is within that function. However -there are some tradeoffs in debugging. Local (".L") labels are not -visible to the debugger, so the following limitations may be observed -during debugging: -- You cannot set a breakpoint on a local label inside a function. -- Disassembly will show the entire function, but will get out of sync and - show incorrect opcodes if it crosses any padding before an aligned local - branch target (".L" label, not ".Ln"). Restart disassembly specifying an - address range explicitly between points where there is padding. -Since FreeRTOS is provided in source form, it is not difficult to remove -the ".L" and ".Ln" prefixes from local labels if you want them visible. -They can also be made visible by passing the '-L' option to the assembler -and linker (see the assembler and linker manuals for details). - - -Interrupt and Exception Handling --------------------------------- - -FreeRTOS provides a complete set of efficient exception and first-level -interrupt handlers installed at the appropriate exception and interrupt -vector locations. The Xtensa architecture supports several different -classes of exceptions and interrupts. Being a configurable architecture, -many of these are optional, and the vector locations are determined by -your processor configuration. (Note that Diamond cores are pre-configured -with specific vector locations.) The handlers provided use conditional -compilation to adapt to your processor configuration and include only -the code that is needed. - -Xtensa vector locations may reside almost anywhere, including in ROM. -The amount of code space available at each of these locations is -often very small (e.g. due to following vectors). A small stub of -code installed at the vector jumps to the corresponding handler, -usually in RAM. The exception and interrupt handlers are defined in -xtensa_vectors.S. They are not specific to FreeRTOS, but call into -FreeRTOS where appropriate via macros defined in xtensa_rtos.h . - -The handlers provided for low and medium priority interrupts are just -dispatchers that save relevant state and call user-definable handlers. -See the files xtensa_vectors.S and xtensa_api.h for more details of how -to create and install application-specific user interrupt handlers. -Similarly, user-defined handlers can be installed for exceptions (other -than a few which are always handled by the OS). - -The high priority interrupt handlers provided may be considered templates -into which the application adds code to service specific interrupts. -The places where application handlers should be inserted are tagged with -the comment "USER_EDIT" in xtensa_vectors.S. - -This FreeRTOS port supports strict priority-based nesting of interrupts. -An interrupt may only nest on top of one of strictly lower priority. -Equal priority interrupts concurrently pending are handled in an -application-defined sequence before any lower priority interrupts -are handled. During interrupt and exception handling, the processor's -interrupt level (PS.INTLEVEL) is used to control the interrupt priority -level that can be accepted; interrupt sources are not controlled -individually by FreeRTOS (the application is free to access the INTENABLE -register directly to enable/disable individual interrupts, eg. using -Xtensa HAL services). This approach provides the most deterministic -bounds on interrupt latency (for a given priority) and stack depth. - -Software prioritization of interrupts at the same priority is controlled -by the definition of XT_USE_SWPRI. See above for a description of this -parameter. - -The following subsections describe the handling of each class of exception -and interrupt in more detail. Many have nothing to do with FreeRTOS but -are mentioned because there is code to handle them in xtensa_vectors.S. - -User Exception and Interrupt Handler (Low/Medium Priority): - - All Xtensa 'general exceptions' come to the user, kernel, or double - exception vector. The exception type is identified by the EXCCAUSE - special register (level 1 interrupts are one particular cause of a - general exception). This port sets up PS to direct all such exceptions - to the user vector. Exceptions taken at the other two vectors usually - indicate a kernel or application bug. - - Level 1 interrupts are identified at the beginning of the handler - and are dispatched to a dedicated handler. Then, syscall and alloca - exceptions are identified and dispatched to special handlers described - below. After this, coprocessor exceptions are identified and dispatched - to the coprocessor handler. - - Any remaining exceptions are processed as follows: - - Having allocated the exception stack frame, the user exception handler - saves the current task state and sets up a C environment and enables - the high-priority class of interrupts (which do not interact with - FreeRTOS), then reads EXCCAUSE and uses the cause (number) to index - into a table of user-specified handlers. The correct handler is then - called. If the handler returns, the context is restored and control is - returned to the code that caused the exception. The user-defined handler - may alter the saved context, or any other system state, that allows the - faulting instruction to be retried. - - If the cause is a level 1 (low-priority) or medium-priority interrupt, - the handler enables all interrupts above that priority level after - saving the task context. It then sets up the environment for C code - and then calls the handler (found in the handler table) for the - interrupt number. If the user has not specified a handler, then the - default handler will be called, which will terminate the program. - - If the interrupt is for the system timer, it calls a special interrupt - handler for the system timer tick, which calls _frxt_timer_int then - clears its bit from the mask. This interrupt cannot be hooked by the - user-defined handler. - - Finally, the handler calls _frxt_int_exit to allow FreeRTOS to perform - any scheduling necessary and return either to the interrupted task - or another. - - If software prioritization is enabled, the handler will re-enable all - interrupts at the same level that are numerically higher than the current - one, before calling the user handler. This allows a higher priority - interrupt to pre-empt the lower priority handler. - -Medium Priority Interrupt Handlers: - - Medium priority interrupts are those at levels 2 up to XCHAL_EXCM_LEVEL, - a configuration-specific maximum interrupt level affected by the global - 'exception mode' bit in the processor status word (PS.EXCM). - Interrupt levels above XCHAL_EXCM_LEVEL are of the high-priority class. - The Xtensa hardware documentation considers medium priority interrupts - to be a special case of high-priority interrupts, but from a software - perspective they are very different. - - Dispatch of medium-priority interrupts is discussed in the section - above. - -High Priority Interrupt Handlers: - - High priority interrupts are those strictly above XCHAL_EXCM_LEVEL, - a configuration-specific maximum interrupt level affected by the - global 'exception mode' bit in the processor status word (PS.EXCM). - High priority handlers may not directly interact with FreeRTOS at all, - and are described here only for the sake of completeness. They must - be coded in assembler (may not be coded in C) and are intended to be - used for handling extremely high frequency hardware events that need - to be handled in only a few cycles. A high priority interrupt handler - may trigger a software interrupt at a medium or low priority level to - occasionally signal FreeRTOS. Please see Xtensa documentation. - - There is a separate vector and a few special registers for each high - priority interrupt, providing for fast dispatch and efficient nesting - on top of lower priority interrupts. Handlers are templates included - only for the vectors that exist in your Xtensa processor configuration. - These templates are written for only one interrupt per high priority - level to minimize latency servicing very fast time-critical interrupts. - The vector code jumps to the corresponding first-level interrupt handler, - which then executes application-provided assembler code before returning - quickly to the interrupted task or lower priority handler. - -Kernel Exception Handler: - - Kernel mode is not used in this port of FreeRTOS, and therefore kernel - exceptions should not happen. A stub is provided for the vector that - triggers the debugger (if connected) or calls _xt_panic to freeze the - processor should a kernel exception occur. - -Alloca Exception Handler: - - Alloca exceptions are generated by the 'movsp' instruction, which - is used only in the windowed ABI. Its purpose is to allocate some - space on top of the stack. Because the window hardware may have - spilled some registers to the 16 byte "base save" area below the - stack pointer, it is necessary to protect those values. The alloca - handler accomplishes this quickly without setting up an interrupt - frame or entering FreeRTOS, by emulating a register underflow and - re-executing 'movsp'. - -Syscall Exception Handler: - - Syscall exceptions are generated by a 'syscall' instruction. - The windowed ABI specifies that executing this instruction with - a value of zero in register a2 must spill any unsaved registers - in the windowed register file to their pre-determined locations - on the caller's stack. The handler does exactly that, and skips - over the 'syscall' instruction before returning to the caller. - If a2 is non-zero, the handler returns a2 == -1 to the caller. - -Co-Processor Exception Handler: - - A co-processor exception is generated when a task accesses a - co-processor that it does not "own". Ownership represents which - task's state is currently in the co-processor. Co-processors are - context-switched "lazily" (on demand) only when a non-owning task - uses a co-processor instruction, otherwise a task retains ownership - even when it is preempted from the main processor. The co-processor - exception handler performs the context-switch and manages ownership. - - Co-processors may not be used by any code outside the context of a - task. A co-processor exception triggered by code that is not part - of a running task is a fatal error and FreeRTOS for Xtensa will panic. - This restriction is intended to reduce the overhead of saving and - restoring co-processor state (which can be quite large) and in - particular remove that overhead from interrupt handlers. - -Debug Exception Handler: - - A debug exception is caused as a result of running code, such as by - a 'break' instruction or hardware breakpoints and watchpoints, or - as a result of an external debug interrupt, such as from an OCD based - debugger or multiprocessor debug events ("breakin/breakout"). If the - processor is running in OCD mode under control of an OCD-based debugger, - the trigger event immediately halts the processor and gives control to - the OCD debugger. Otherwise control is transferred to the debug vector. - The debug vector handler calls the simulator if running on the ISS, - which then takes control and interacts with any attached debugger. - If running on hardware and not in OCD mode, debug exceptions are not - expected, so the debug handler calls _xt_panic to freeze the processor. - -Double Exception Handler: - - A double exception is a general exception that happens while the - processor is in exception mode (PS.EXCM set), and thus indicates a - bug in kernel code. The double exception vector handler triggers - the debugger (if connected) or calls _xt_panic to freeze the - processor. - -Window Overflow and Underflow Exception Handlers: - - Window overflow and underflow handlers are required for use of the - windowed ABI. Each has its own dedicated vector and highly optimized - code that is independent of OS. See Xtensa documentation for details. - -Hooks for Dynamic Installation of Handlers: - - Optional hooks are provided in the user exception and low level - interrupt handler and all medium and high priority interrupt handlers, - to dynamically install a handler function (which may be coded in C, - unless in a high-priority interrupt handler). These hooks are enabled - and used by automatic regression tests, they are not part of a normal - FreeRTOS build. However an application is free to take advantage of - them. The interrupt/exception hooks are described in xtensa_rtos.h . - - It is recommended that the application not make use of these hooks, but - rather use xt_set_interrupt_handler() and xt_set_exception_handler() - to install application-specific handlers. This method is more convenient - and allows arguments to be passed to the handlers. Software prioritization - of interrupts works only with this method. See xtensa_api.h for details. - -Overlay Support - - Code overlays are currently not supported for FreeRTOS. This will be - supported in a future release. Make sure that the option XT_USE_OVLY is - never defined when building. - +Please see the Xtensa-specific README in this location for more details. -End- diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_api.h b/portable/ThirdParty/XCC/Xtensa/xtensa_api.h deleted file mode 100644 index bf2834f09..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_api.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Xtensa-specific API for RTOS ports. - */ - -#ifndef __XTENSA_API_H__ -#define __XTENSA_API_H__ - -#include - -#include "xtensa_context.h" - - -/* Typedef for C-callable interrupt handler function */ -typedef void (* xt_handler)( void * ); - -/* Typedef for C-callable exception handler function */ -typedef void (* xt_exc_handler)( XtExcFrame * ); - - -/* - * ------------------------------------------------------------------------------- - * Call this function to set a handler for the specified exception. - * - * n - Exception number (type) - * f - Handler function address, NULL to uninstall handler. - * - * The handler will be passed a pointer to the exception frame, which is created - * on the stack of the thread that caused the exception. - * - * If the handler returns, the thread context will be restored and the faulting - * instruction will be retried. Any values in the exception frame that are - * modified by the handler will be restored as part of the context. For details - * of the exception frame structure see xtensa_context.h. - * ------------------------------------------------------------------------------- - */ -extern xt_exc_handler xt_set_exception_handler( int n, - xt_exc_handler f ); - - -/* - * ------------------------------------------------------------------------------- - * Call this function to set a handler for the specified interrupt. - * - * n - Interrupt number. - * f - Handler function address, NULL to uninstall handler. - * arg - Argument to be passed to handler. - * ------------------------------------------------------------------------------- - */ -extern xt_handler xt_set_interrupt_handler( int n, - xt_handler f, - void * arg ); - - -/* - * ------------------------------------------------------------------------------- - * Call this function to enable the specified interrupts. - * - * mask - Bit mask of interrupts to be enabled. - * - * Returns the previous state of the interrupt enables. - * ------------------------------------------------------------------------------- - */ -extern unsigned int xt_ints_on( unsigned int mask ); - - -/* - * ------------------------------------------------------------------------------- - * Call this function to disable the specified interrupts. - * - * mask - Bit mask of interrupts to be disabled. - * - * Returns the previous state of the interrupt enables. - * ------------------------------------------------------------------------------- - */ -extern unsigned int xt_ints_off( unsigned int mask ); - - -/* - * ------------------------------------------------------------------------------- - * Call this function to set the specified (s/w) interrupt. - * ------------------------------------------------------------------------------- - */ -static inline void xt_set_intset( unsigned int arg ) -{ - xthal_set_intset( arg ); -} - - -/* - * ------------------------------------------------------------------------------- - * Call this function to clear the specified (s/w or edge-triggered) - * interrupt. - * ------------------------------------------------------------------------------- - */ -static inline void xt_set_intclear( unsigned int arg ) -{ - xthal_set_intclear( arg ); -} - - -#endif /* __XTENSA_API_H__ */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_config.h b/portable/ThirdParty/XCC/Xtensa/xtensa_config.h deleted file mode 100644 index cf80f8190..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_config.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Configuration-specific information for Xtensa build. This file must be - * included in FreeRTOSConfig.h to properly set up the config-dependent - * parameters correctly. - * - * NOTE: To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must - * be defined to be > 0 somewhere above or on the command line. - */ - -#ifndef XTENSA_CONFIG_H -#define XTENSA_CONFIG_H - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -#include -#include -#include /* required for XSHAL_CLIB */ - -#include "xtensa_context.h" - - -/*----------------------------------------------------------------------------- - * STACK REQUIREMENTS - * - * This section defines the minimum stack size, and the extra space required to - * be allocated for saving coprocessor state and/or C library state information - * (if thread safety is enabled for the C library). The sizes are in bytes. - * - * Stack sizes for individual tasks should be derived from these minima based on - * the maximum call depth of the task and the maximum level of interrupt nesting. - * A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum is based - * on the requirement for a task that calls nothing else but can be interrupted. - * This assumes that interrupt handlers do not call more than a few levels deep. - * If this is not true, i.e. one or more interrupt handlers make deep calls then - * the minimum must be increased. - * - * If the Xtensa processor configuration includes coprocessors, then space is - * allocated to save the coprocessor state on the stack. - * - * If thread safety is enabled for the C runtime library, (XT_USE_THREAD_SAFE_CLIB - * is defined) then space is allocated to save the C library context in the TCB. - * - * Allocating insufficient stack space is a common source of hard-to-find errors. - * During development, it is best to enable the FreeRTOS stack checking features. - * - * Usage: - * - * XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable thread-safe - * use of the C library. This will require extra stack - * space to be allocated for tasks that use the C library - * reentrant functions. See below for more information. - * - * NOTE: The Xtensa toolchain supports multiple C libraries and not all of them - * support thread safety. Check your core configuration to see which C library - * was chosen for your system. - * - * XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is recommended - * that you do not use a stack smaller than this for any - * task. In case you want to use stacks smaller than this - * size, you must verify that the smaller size(s) will work - * under all operating conditions. - * - * XT_STACK_EXTRA -- The amount of extra stack space to allocate for a task - * that does not make C library reentrant calls. Add this - * to the amount of stack space required by the task itself. - * - * XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library state. - * - * -----------------------------------------------------------------------------*/ - -/* Extra space required for interrupt/exception hooks. */ -#ifdef XT_INTEXC_HOOKS - #ifdef __XTENSA_CALL0_ABI__ - #define STK_INTEXC_EXTRA 0x200 - #else - #define STK_INTEXC_EXTRA 0x180 - #endif -#else - #define STK_INTEXC_EXTRA 0 -#endif - -/* Check C library thread safety support and compute size of C library save area. - * For the supported libraries, we enable thread safety by default, and this can - * be overridden from the compiler/make command line. */ -#if ( XSHAL_CLIB == XTHAL_CLIB_NEWLIB ) || ( XSHAL_CLIB == XTHAL_CLIB_XCLIB ) - #ifndef XT_USE_THREAD_SAFE_CLIB - #define XT_USE_THREAD_SAFE_CLIB 1 - #endif -#else - #define XT_USE_THREAD_SAFE_CLIB 0 -#endif - -#if XT_USE_THREAD_SAFE_CLIB > 0u - #if XSHAL_CLIB == XTHAL_CLIB_XCLIB - #define XT_HAVE_THREAD_SAFE_CLIB 1 - #if !defined __ASSEMBLER__ - #include - #define XT_CLIB_CONTEXT_AREA_SIZE ( ( sizeof( struct _reent ) + 15 ) + ( -16 ) ) - #define XT_CLIB_GLOBAL_PTR _reent_ptr - #define _REENT_INIT_PTR _init_reent - #define _impure_ptr _reent_ptr - - void _reclaim_reent( void * ptr ); - #endif - #elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB - #define XT_HAVE_THREAD_SAFE_CLIB 1 - #if !defined __ASSEMBLER__ - #include - #define XT_CLIB_CONTEXT_AREA_SIZE ( ( sizeof( struct _reent ) + 15 ) + ( -16 ) ) - #define XT_CLIB_GLOBAL_PTR _impure_ptr - #endif - #else /* if XSHAL_CLIB == XTHAL_CLIB_XCLIB */ - #define XT_HAVE_THREAD_SAFE_CLIB 0 - #error The selected C runtime library is not thread safe. - #endif /* if XSHAL_CLIB == XTHAL_CLIB_XCLIB */ -#else /* if XT_USE_THREAD_SAFE_CLIB > 0u */ - #define XT_CLIB_CONTEXT_AREA_SIZE 0 -#endif /* if XT_USE_THREAD_SAFE_CLIB > 0u */ - -/*------------------------------------------------------------------------------ - * Extra size -- interrupt frame plus coprocessor save area plus hook space. - * NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the hooks. - * ------------------------------------------------------------------------------*/ -#ifdef __XTENSA_CALL0_ABI__ - #define XT_XTRA_SIZE ( XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE ) -#else - #define XT_XTRA_SIZE ( XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE ) -#endif - -/*------------------------------------------------------------------------------ - * Space allocated for user code -- function calls and local variables. - * NOTE: This number can be adjusted to suit your needs. You must verify that the - * amount of space you reserve is adequate for the worst-case conditions in your - * application. - * NOTE: The windowed ABI requires more stack, since space has to be reserved - * for spilling register windows. - * ------------------------------------------------------------------------------*/ -#ifdef __XTENSA_CALL0_ABI__ - #define XT_USER_SIZE 0x200 -#else - #define XT_USER_SIZE 0x400 -#endif - -/* Minimum recommended stack size. */ -#define XT_STACK_MIN_SIZE ( ( XT_XTRA_SIZE + XT_USER_SIZE ) / sizeof( unsigned char ) ) - -/* OS overhead with and without C library thread context. */ -#define XT_STACK_EXTRA ( XT_XTRA_SIZE ) -#define XT_STACK_EXTRA_CLIB ( XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE ) - - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* XTENSA_CONFIG_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_context.S b/portable/ThirdParty/XCC/Xtensa/xtensa_context.S deleted file mode 100644 index 96507e1c8..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_context.S +++ /dev/null @@ -1,630 +0,0 @@ - /* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * XTENSA CONTEXT SAVE AND RESTORE ROUTINES - * - * Low-level Call0 functions for handling generic context save and restore of - * registers not specifically addressed by the interrupt vectors and handlers. - * Those registers (not handled by these functions) are PC, PS, A0, A1 (SP). - * Except for the calls to RTOS functions, this code is generic to Xtensa. - * - * Note that in Call0 ABI, interrupt handlers are expected to preserve the callee- - * save regs (A12-A15), which is always the case if the handlers are coded in C. - * However A12, A13 are made available as scratch registers for interrupt dispatch - * code, so are presumed saved anyway, and are always restored even in Call0 ABI. - * Only A14, A15 are truly handled as callee-save regs. - * - * Because Xtensa is a configurable architecture, this port supports all user - * generated configurations (except restrictions stated in the release notes). - * This is accomplished by conditional compilation using macros and functions - * defined in the Xtensa HAL (hardware adaptation layer) for your configuration. - * Only the processor state included in your configuration is saved and restored, - * including any processor state added by user configuration options or TIE. - */ - -/* Warn nicely if this file gets named with a lowercase .s instead of .S: */ -#define NOERROR # -NOERROR: .error "C preprocessor needed for this file: make sure its filename\ - ends in uppercase .S, or use xt-xcc's -x assembler-with-cpp option." - - -#include "xtensa_rtos.h" - -#ifdef XT_USE_OVLY -#include -#endif - - .text - .literal_position - -/******************************************************************************* - -_xt_context_save - - !! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !! - -Saves all Xtensa processor state except PC, PS, A0, A1 (SP), A12, A13, in the -interrupt stack frame defined in xtensa_rtos.h. -Its counterpart is _xt_context_restore (which also restores A12, A13). - -Caller is expected to have saved PC, PS, A0, A1 (SP), A12, A13 in the frame. -This function preserves A12 & A13 in order to provide the caller with 2 scratch -regs that need not be saved over the call to this function. The choice of which -2 regs to provide is governed by xthal_window_spill_nw and xthal_save_extra_nw, -to avoid moving data more than necessary. Caller can assign regs accordingly. - -Entry Conditions: - A0 = Return address in caller. - A1 = Stack pointer of interrupted thread or handler ("interruptee"). - Original A12, A13 have already been saved in the interrupt stack frame. - Other processor state except PC, PS, A0, A1 (SP), A12, A13, is as at the - point of interruption. - If windowed ABI, PS.EXCM = 1 (exceptions disabled). - -Exit conditions: - A0 = Return address in caller. - A1 = Stack pointer of interrupted thread or handler ("interruptee"). - A12, A13 as at entry (preserved). - If windowed ABI, PS.EXCM = 1 (exceptions disabled). - -*******************************************************************************/ - - .global _xt_context_save - .type _xt_context_save,@function - .align 4 -_xt_context_save: - - s32i a2, sp, XT_STK_A2 - s32i a3, sp, XT_STK_A3 - s32i a4, sp, XT_STK_A4 - s32i a5, sp, XT_STK_A5 - s32i a6, sp, XT_STK_A6 - s32i a7, sp, XT_STK_A7 - s32i a8, sp, XT_STK_A8 - s32i a9, sp, XT_STK_A9 - s32i a10, sp, XT_STK_A10 - s32i a11, sp, XT_STK_A11 - - /* - Call0 ABI callee-saved regs a12-15 do not need to be saved here. - a12-13 are the caller's responsibility so it can use them as scratch. - So only need to save a14-a15 here for Windowed ABI (not Call0). - */ - #ifndef __XTENSA_CALL0_ABI__ - s32i a14, sp, XT_STK_A14 - s32i a15, sp, XT_STK_A15 - #endif - - rsr a3, SAR - s32i a3, sp, XT_STK_SAR - - #if XCHAL_HAVE_LOOPS - rsr a3, LBEG - s32i a3, sp, XT_STK_LBEG - rsr a3, LEND - s32i a3, sp, XT_STK_LEND - rsr a3, LCOUNT - s32i a3, sp, XT_STK_LCOUNT - #endif - - #if XT_USE_SWPRI - /* Save virtual priority mask */ - movi a3, _xt_vpri_mask - l32i a3, a3, 0 - s32i a3, sp, XT_STK_VPRI - #endif - - #if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__) - mov a9, a0 /* preserve ret addr */ - #endif - - #ifndef __XTENSA_CALL0_ABI__ - /* - To spill the reg windows, temp. need pre-interrupt stack ptr and a4-15. - Need to save a9,12,13 temporarily (in frame temps) and recover originals. - Interrupts need to be disabled below XCHAL_EXCM_LEVEL and window overflow - and underflow exceptions disabled (assured by PS.EXCM == 1). - */ - s32i a12, sp, XT_STK_TMP0 /* temp. save stuff in stack frame */ - s32i a13, sp, XT_STK_TMP1 - s32i a9, sp, XT_STK_TMP2 - - /* - Save the overlay state if we are supporting overlays. Since we just saved - three registers, we can conveniently use them here. Note that as of now, - overlays only work for windowed calling ABI. - */ - #ifdef XT_USE_OVLY - l32i a9, sp, XT_STK_PC /* recover saved PC */ - _xt_overlay_get_state a9, a12, a13 - s32i a9, sp, XT_STK_OVLY /* save overlay state */ - #endif - - l32i a12, sp, XT_STK_A12 /* recover original a9,12,13 */ - l32i a13, sp, XT_STK_A13 - l32i a9, sp, XT_STK_A9 - addi sp, sp, XT_STK_FRMSZ /* restore the interruptee's SP */ - call0 xthal_window_spill_nw /* preserves only a4,5,8,9,12,13 */ - addi sp, sp, -XT_STK_FRMSZ - l32i a12, sp, XT_STK_TMP0 /* recover stuff from stack frame */ - l32i a13, sp, XT_STK_TMP1 - l32i a9, sp, XT_STK_TMP2 - #endif - - #if XCHAL_EXTRA_SA_SIZE > 0 - /* - NOTE: Normally the xthal_save_extra_nw macro only affects address - registers a2-a5. It is theoretically possible for Xtensa processor - designers to write TIE that causes more address registers to be - affected, but it is generally unlikely. If that ever happens, - more registers need to be saved/restored around this macro invocation. - Here we assume a9,12,13 are preserved. - Future Xtensa tools releases might limit the regs that can be affected. - */ - addi a2, sp, XT_STK_EXTRA /* where to save it */ - # if XCHAL_EXTRA_SA_ALIGN > 16 - movi a3, -XCHAL_EXTRA_SA_ALIGN - and a2, a2, a3 /* align dynamically >16 bytes */ - # endif - call0 xthal_save_extra_nw /* destroys a0,2,3,4,5 */ - #endif - - #if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__) - mov a0, a9 /* retrieve ret addr */ - #endif - - ret - -/******************************************************************************* - -_xt_context_restore - - !! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !! - -Restores all Xtensa processor state except PC, PS, A0, A1 (SP) (and in Call0 -ABI, A14, A15 which are preserved by all interrupt handlers) from an interrupt -stack frame defined in xtensa_rtos.h . -Its counterpart is _xt_context_save (whose caller saved A12, A13). - -Caller is responsible to restore PC, PS, A0, A1 (SP). - -Entry Conditions: - A0 = Return address in caller. - A1 = Stack pointer of interrupted thread or handler ("interruptee"). - -Exit conditions: - A0 = Return address in caller. - A1 = Stack pointer of interrupted thread or handler ("interruptee"). - Other processor state except PC, PS, A0, A1 (SP), is as at the point - of interruption. - -*******************************************************************************/ - - .global _xt_context_restore - .type _xt_context_restore,@function - .align 4 -_xt_context_restore: - - #if XCHAL_EXTRA_SA_SIZE > 0 - /* - NOTE: Normally the xthal_restore_extra_nw macro only affects address - registers a2-a5. It is theoretically possible for Xtensa processor - designers to write TIE that causes more address registers to be - affected, but it is generally unlikely. If that ever happens, - more registers need to be saved/restored around this macro invocation. - Here we only assume a13 is preserved. - Future Xtensa tools releases might limit the regs that can be affected. - */ - mov a13, a0 /* preserve ret addr */ - addi a2, sp, XT_STK_EXTRA /* where to find it */ - # if XCHAL_EXTRA_SA_ALIGN > 16 - movi a3, -XCHAL_EXTRA_SA_ALIGN - and a2, a2, a3 /* align dynamically >16 bytes */ - # endif - call0 xthal_restore_extra_nw /* destroys a0,2,3,4,5 */ - mov a0, a13 /* retrieve ret addr */ - #endif - - #if XCHAL_HAVE_LOOPS - l32i a2, sp, XT_STK_LBEG - l32i a3, sp, XT_STK_LEND - wsr a2, LBEG - l32i a2, sp, XT_STK_LCOUNT - wsr a3, LEND - wsr a2, LCOUNT - #endif - - #ifdef XT_USE_OVLY - /* - If we are using overlays, this is a good spot to check if we need - to restore an overlay for the incoming task. Here we have a bunch - of registers to spare. Note that this step is going to use a few - bytes of storage below SP (SP-20 to SP-32) if an overlay is going - to be restored. - */ - l32i a2, sp, XT_STK_PC /* retrieve PC */ - l32i a3, sp, XT_STK_PS /* retrieve PS */ - l32i a4, sp, XT_STK_OVLY /* retrieve overlay state */ - l32i a5, sp, XT_STK_A1 /* retrieve stack ptr */ - _xt_overlay_check_map a2, a3, a4, a5, a6 - s32i a2, sp, XT_STK_PC /* save updated PC */ - s32i a3, sp, XT_STK_PS /* save updated PS */ - #endif - - #ifdef XT_USE_SWPRI - /* Restore virtual interrupt priority and interrupt enable */ - movi a3, _xt_intdata - l32i a4, a3, 0 /* a4 = _xt_intenable */ - l32i a5, sp, XT_STK_VPRI /* a5 = saved _xt_vpri_mask */ - and a4, a4, a5 - wsr a4, INTENABLE /* update INTENABLE */ - s32i a5, a3, 4 /* restore _xt_vpri_mask */ - #endif - - l32i a3, sp, XT_STK_SAR - l32i a2, sp, XT_STK_A2 - wsr a3, SAR - l32i a3, sp, XT_STK_A3 - l32i a4, sp, XT_STK_A4 - l32i a5, sp, XT_STK_A5 - l32i a6, sp, XT_STK_A6 - l32i a7, sp, XT_STK_A7 - l32i a8, sp, XT_STK_A8 - l32i a9, sp, XT_STK_A9 - l32i a10, sp, XT_STK_A10 - l32i a11, sp, XT_STK_A11 - - /* - Call0 ABI callee-saved regs a12-15 do not need to be restored here. - However a12-13 were saved for scratch before XT_RTOS_INT_ENTER(), - so need to be restored anyway, despite being callee-saved in Call0. - */ - l32i a12, sp, XT_STK_A12 - l32i a13, sp, XT_STK_A13 - #ifndef __XTENSA_CALL0_ABI__ - l32i a14, sp, XT_STK_A14 - l32i a15, sp, XT_STK_A15 - #endif - - ret - - -/******************************************************************************* - -_xt_coproc_init - -Initializes global co-processor management data, setting all co-processors -to "unowned". Leaves CPENABLE as it found it (does NOT clear it). - -Called during initialization of the RTOS, before any threads run. - -This may be called from normal Xtensa single-threaded application code which -might use co-processors. The Xtensa run-time initialization enables all -co-processors. They must remain enabled here, else a co-processor exception -might occur outside of a thread, which the exception handler doesn't expect. - -Entry Conditions: - Xtensa single-threaded run-time environment is in effect. - No thread is yet running. - -Exit conditions: - None. - -Obeys ABI conventions per prototype: - void _xt_coproc_init(void) - -*******************************************************************************/ - -#if XCHAL_CP_NUM > 0 - - .global _xt_coproc_init - .type _xt_coproc_init,@function - .align 4 -_xt_coproc_init: - ENTRY0 - - /* Initialize thread co-processor ownerships to 0 (unowned). */ - movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */ - addi a3, a2, XCHAL_CP_MAX << 2 /* a3 = top+1 of owner array */ - movi a4, 0 /* a4 = 0 (unowned) */ -1: s32i a4, a2, 0 - addi a2, a2, 4 - bltu a2, a3, 1b - - RET0 - -#endif - - -/******************************************************************************* - -_xt_coproc_release - -Releases any and all co-processors owned by a given thread. The thread is -identified by it's co-processor state save area defined in xtensa_context.h . - -Must be called before a thread's co-proc save area is deleted to avoid -memory corruption when the exception handler tries to save the state. -May be called when a thread terminates or completes but does not delete -the co-proc save area, to avoid the exception handler having to save the -thread's co-proc state before another thread can use it (optimization). - -Entry Conditions: - A2 = Pointer to base of co-processor state save area. - -Exit conditions: - None. - -Obeys ABI conventions per prototype: - void _xt_coproc_release(void * coproc_sa_base) - -*******************************************************************************/ - -#if XCHAL_CP_NUM > 0 - - .global _xt_coproc_release - .type _xt_coproc_release,@function - .align 4 -_xt_coproc_release: - ENTRY0 /* a2 = base of save area */ - - movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */ - addi a4, a3, XCHAL_CP_MAX << 2 /* a4 = top+1 of owner array */ - movi a5, 0 /* a5 = 0 (unowned) */ - - rsil a6, XCHAL_EXCM_LEVEL /* lock interrupts */ - -1: l32i a7, a3, 0 /* a7 = owner at a3 */ - bne a2, a7, 2f /* if (coproc_sa_base == owner) */ - s32i a5, a3, 0 /* owner = unowned */ -2: addi a3, a3, 1<<2 /* a3 = next entry in owner array */ - bltu a3, a4, 1b /* repeat until end of array */ - -3: wsr a6, PS /* restore interrupts */ - - RET0 - -#endif - - -/******************************************************************************* -_xt_coproc_savecs - -If there is a current thread and it has a coprocessor state save area, then -save all callee-saved state into this area. This function is called from the -solicited context switch handler. It calls a system-specific function to get -the coprocessor save area base address. - -Entry conditions: - - The thread being switched out is still the current thread. - - CPENABLE state reflects which coprocessors are active. - - Registers have been saved/spilled already. - -Exit conditions: - - All necessary CP callee-saved state has been saved. - - Registers a2-a7, a13-a15 have been trashed. - -Must be called from assembly code only, using CALL0. -*******************************************************************************/ -#if XCHAL_CP_NUM > 0 - - .extern _xt_coproc_sa_offset /* external reference */ - - .global _xt_coproc_savecs - .type _xt_coproc_savecs,@function - .align 4 -_xt_coproc_savecs: - - /* At entry, CPENABLE should be showing which CPs are enabled. */ - - rsr a2, CPENABLE /* a2 = which CPs are enabled */ - beqz a2, .Ldone /* quick exit if none */ - mov a14, a0 /* save return address */ - call0 XT_RTOS_CP_STATE /* get address of CP save area */ - mov a0, a14 /* restore return address */ - beqz a15, .Ldone /* if none then nothing to do */ - s16i a2, a15, XT_CP_CS_ST /* save mask of CPs being stored */ - movi a13, _xt_coproc_sa_offset /* array of CP save offsets */ - l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */ - -#if XCHAL_CP0_SA_SIZE - bbci.l a2, 0, 2f /* CP 0 not enabled */ - l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */ - add a3, a14, a15 /* a3 = save area for CP 0 */ - xchal_cp0_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP1_SA_SIZE - bbci.l a2, 1, 2f /* CP 1 not enabled */ - l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */ - add a3, a14, a15 /* a3 = save area for CP 1 */ - xchal_cp1_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP2_SA_SIZE - bbci.l a2, 2, 2f - l32i a14, a13, 8 - add a3, a14, a15 - xchal_cp2_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP3_SA_SIZE - bbci.l a2, 3, 2f - l32i a14, a13, 12 - add a3, a14, a15 - xchal_cp3_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP4_SA_SIZE - bbci.l a2, 4, 2f - l32i a14, a13, 16 - add a3, a14, a15 - xchal_cp4_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP5_SA_SIZE - bbci.l a2, 5, 2f - l32i a14, a13, 20 - add a3, a14, a15 - xchal_cp5_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP6_SA_SIZE - bbci.l a2, 6, 2f - l32i a14, a13, 24 - add a3, a14, a15 - xchal_cp6_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP7_SA_SIZE - bbci.l a2, 7, 2f - l32i a14, a13, 28 - add a3, a14, a15 - xchal_cp7_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -.Ldone: - ret -#endif - - -/******************************************************************************* -_xt_coproc_restorecs - -Restore any callee-saved coprocessor state for the incoming thread. -This function is called from coprocessor exception handling, when giving -ownership to a thread that solicited a context switch earlier. It calls a -system-specific function to get the coprocessor save area base address. - -Entry conditions: - - The incoming thread is set as the current thread. - - CPENABLE is set up correctly for all required coprocessors. - - a2 = mask of coprocessors to be restored. - -Exit conditions: - - All necessary CP callee-saved state has been restored. - - CPENABLE - unchanged. - - Registers a2-a7, a13-a15 have been trashed. - -Must be called from assembly code only, using CALL0. -*******************************************************************************/ -#if XCHAL_CP_NUM > 0 - - .global _xt_coproc_restorecs - .type _xt_coproc_restorecs,@function - .align 4 -_xt_coproc_restorecs: - - mov a14, a0 /* save return address */ - call0 XT_RTOS_CP_STATE /* get address of CP save area */ - mov a0, a14 /* restore return address */ - beqz a15, .Ldone2 /* if none then nothing to do */ - l16ui a3, a15, XT_CP_CS_ST /* a3 = which CPs have been saved */ - xor a3, a3, a2 /* clear the ones being restored */ - s32i a3, a15, XT_CP_CS_ST /* update saved CP mask */ - movi a13, _xt_coproc_sa_offset /* array of CP save offsets */ - l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */ - -#if XCHAL_CP0_SA_SIZE - bbci.l a2, 0, 2f /* CP 0 not enabled */ - l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */ - add a3, a14, a15 /* a3 = save area for CP 0 */ - xchal_cp0_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP1_SA_SIZE - bbci.l a2, 1, 2f /* CP 1 not enabled */ - l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */ - add a3, a14, a15 /* a3 = save area for CP 1 */ - xchal_cp1_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP2_SA_SIZE - bbci.l a2, 2, 2f - l32i a14, a13, 8 - add a3, a14, a15 - xchal_cp2_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP3_SA_SIZE - bbci.l a2, 3, 2f - l32i a14, a13, 12 - add a3, a14, a15 - xchal_cp3_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP4_SA_SIZE - bbci.l a2, 4, 2f - l32i a14, a13, 16 - add a3, a14, a15 - xchal_cp4_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP5_SA_SIZE - bbci.l a2, 5, 2f - l32i a14, a13, 20 - add a3, a14, a15 - xchal_cp5_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP6_SA_SIZE - bbci.l a2, 6, 2f - l32i a14, a13, 24 - add a3, a14, a15 - xchal_cp6_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -#if XCHAL_CP7_SA_SIZE - bbci.l a2, 7, 2f - l32i a14, a13, 28 - add a3, a14, a15 - xchal_cp7_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL -2: -#endif - -.Ldone2: - ret - -#endif diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_context.h b/portable/ThirdParty/XCC/Xtensa/xtensa_context.h deleted file mode 100644 index 5d243d3c0..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_context.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES - * - * This header contains definitions and macros for use primarily by Xtensa - * RTOS assembly coded source files. It includes and uses the Xtensa hardware - * abstraction layer (HAL) to deal with config specifics. It may also be - * included in C source files. - * - * !! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !! - * - * NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes. - */ - -#ifndef XTENSA_CONTEXT_H -#define XTENSA_CONTEXT_H - -#ifdef __ASSEMBLER__ - #include -#endif - -#include -#include -#include - - -/* Align a value up to nearest n-byte boundary, where n is a power of 2. */ -#define ALIGNUP( n, val ) ( ( ( val ) + ( n ) - 1 ) & -( n ) ) - - -/* - * ------------------------------------------------------------------------------- - * Macros that help define structures for both C and assembler. - * ------------------------------------------------------------------------------- - */ -#if defined( _ASMLANGUAGE ) || defined( __ASSEMBLER__ ) - - #define STRUCT_BEGIN .pushsection.text; .struct 0 - #define STRUCT_FIELD( ctype, size, asname, name ) asname :.space size - #define STRUCT_AFIELD( ctype, size, asname, name, n ) asname :.space( size ) *( n ) - #define STRUCT_END( sname ) sname ## Size:; .popsection - -#else - - #define STRUCT_BEGIN typedef struct { - #define STRUCT_FIELD( ctype, size, asname, name ) ctype name; - #define STRUCT_AFIELD( ctype, size, asname, name, n ) ctype name[ n ]; - #define STRUCT_END( sname ) \ -} \ - sname; - -#endif //_ASMLANGUAGE || __ASSEMBLER__ - - -/* - * ------------------------------------------------------------------------------- - * INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT - * - * A stack frame of this structure is allocated for any interrupt or exception. - * It goes on the current stack. If the RTOS has a system stack for handling - * interrupts, every thread stack must allow space for just one interrupt stack - * frame, then nested interrupt stack frames go on the system stack. - * - * The frame includes basic registers (explicit) and "extra" registers introduced - * by user TIE or the use of the MAC16 option in the user's Xtensa config. - * The frame size is minimized by omitting regs not applicable to user's config. - * - * For Windowed ABI, this stack frame includes the interruptee's base save area, - * another base save area to manage gcc nested functions, and a little temporary - * space to help manage the spilling of the register windows. - * ------------------------------------------------------------------------------- - */ - -STRUCT_BEGIN STRUCT_FIELD( long, - 4, - XT_STK_EXIT, - exit ) /* exit point for dispatch */ -STRUCT_FIELD( long, 4, XT_STK_PC, pc ) /* return PC */ -STRUCT_FIELD( long, 4, XT_STK_PS, ps ) /* return PS */ -STRUCT_FIELD( long, 4, XT_STK_A0, a0 ) -STRUCT_FIELD( long, 4, XT_STK_A1, a1 ) /* stack pointer before interrupt */ -STRUCT_FIELD( long, 4, XT_STK_A2, a2 ) -STRUCT_FIELD( long, 4, XT_STK_A3, a3 ) -STRUCT_FIELD( long, 4, XT_STK_A4, a4 ) -STRUCT_FIELD( long, 4, XT_STK_A5, a5 ) -STRUCT_FIELD( long, 4, XT_STK_A6, a6 ) -STRUCT_FIELD( long, 4, XT_STK_A7, a7 ) -STRUCT_FIELD( long, 4, XT_STK_A8, a8 ) -STRUCT_FIELD( long, 4, XT_STK_A9, a9 ) -STRUCT_FIELD( long, 4, XT_STK_A10, a10 ) -STRUCT_FIELD( long, 4, XT_STK_A11, a11 ) -STRUCT_FIELD( long, 4, XT_STK_A12, a12 ) -STRUCT_FIELD( long, 4, XT_STK_A13, a13 ) -STRUCT_FIELD( long, 4, XT_STK_A14, a14 ) -STRUCT_FIELD( long, 4, XT_STK_A15, a15 ) -STRUCT_FIELD( long, 4, XT_STK_SAR, sar ) -STRUCT_FIELD( long, 4, XT_STK_EXCCAUSE, exccause ) -STRUCT_FIELD( long, 4, XT_STK_EXCVADDR, excvaddr ) -#if XCHAL_HAVE_LOOPS - STRUCT_FIELD( long, 4, XT_STK_LBEG, lbeg ) - STRUCT_FIELD( long, 4, XT_STK_LEND, lend ) - STRUCT_FIELD( long, 4, XT_STK_LCOUNT, lcount ) -#endif -#ifndef __XTENSA_CALL0_ABI__ -/* Temporary space for saving stuff during window spill */ - STRUCT_FIELD( long, 4, XT_STK_TMP0, tmp0 ) - STRUCT_FIELD( long, 4, XT_STK_TMP1, tmp1 ) - STRUCT_FIELD( long, 4, XT_STK_TMP2, tmp2 ) -#endif -#ifdef XT_USE_SWPRI -/* Storage for virtual priority mask */ - STRUCT_FIELD( long, 4, XT_STK_VPRI, vpri ) -#endif -#ifdef XT_USE_OVLY -/* Storage for overlay state */ - STRUCT_FIELD( long, 4, XT_STK_OVLY, ovly ) -#endif -STRUCT_END( XtExcFrame ) - -#if defined( _ASMLANGUAGE ) || defined( __ASSEMBLER__ ) -#define XT_STK_NEXT1 XtExcFrameSize -#else -#define XT_STK_NEXT1 sizeof( XtExcFrame ) -#endif - -/* Allocate extra storage if needed */ -#if XCHAL_EXTRA_SA_SIZE != 0 - - #if XCHAL_EXTRA_SA_ALIGN <= 16 -#define XT_STK_EXTRA ALIGNUP( XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1 ) - #else -/* If need more alignment than stack, add space for dynamic alignment */ -#define XT_STK_EXTRA ( ALIGNUP( XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1 ) + XCHAL_EXTRA_SA_ALIGN ) - #endif -#define XT_STK_NEXT2 ( XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE ) - -#else - -#define XT_STK_NEXT2 XT_STK_NEXT1 - -#endif /* if XCHAL_EXTRA_SA_SIZE != 0 */ - -/* - * ------------------------------------------------------------------------------- - * This is the frame size. Add space for 4 registers (interruptee's base save - * area) and some space for gcc nested functions if any. - * ------------------------------------------------------------------------------- - */ -#define XT_STK_FRMSZ ( ALIGNUP( 0x10, XT_STK_NEXT2 ) + 0x20 ) - - -/* - * ------------------------------------------------------------------------------- - * SOLICITED STACK FRAME FOR A THREAD - * - * A stack frame of this structure is allocated whenever a thread enters the - * RTOS kernel intentionally (and synchronously) to submit to thread scheduling. - * It goes on the current thread's stack. - * - * The solicited frame only includes registers that are required to be preserved - * by the callee according to the compiler's ABI conventions, some space to save - * the return address for returning to the caller, and the caller's PS register. - * - * For Windowed ABI, this stack frame includes the caller's base save area. - * - * Note on XT_SOL_EXIT field: - * It is necessary to distinguish a solicited from an interrupt stack frame. - * This field corresponds to XT_STK_EXIT in the interrupt stack frame and is - * always at the same offset (0). It can be written with a code (usually 0) - * to distinguish a solicted frame from an interrupt frame. An RTOS port may - * opt to ignore this field if it has another way of distinguishing frames. - * ------------------------------------------------------------------------------- - */ - -STRUCT_BEGIN -#ifdef __XTENSA_CALL0_ABI__ - STRUCT_FIELD( long, 4, XT_SOL_EXIT, exit ) - STRUCT_FIELD( long, 4, XT_SOL_PC, pc ) - STRUCT_FIELD( long, 4, XT_SOL_PS, ps ) - STRUCT_FIELD( long, 4, XT_SOL_NEXT, next ) - STRUCT_FIELD( long, 4, XT_SOL_A12, a12 ) /* should be on 16-byte alignment */ - STRUCT_FIELD( long, 4, XT_SOL_A13, a13 ) - STRUCT_FIELD( long, 4, XT_SOL_A14, a14 ) - STRUCT_FIELD( long, 4, XT_SOL_A15, a15 ) -#else - STRUCT_FIELD( long, 4, XT_SOL_EXIT, exit ) - STRUCT_FIELD( long, 4, XT_SOL_PC, pc ) - STRUCT_FIELD( long, 4, XT_SOL_PS, ps ) - STRUCT_FIELD( long, 4, XT_SOL_NEXT, next ) - STRUCT_FIELD( long, 4, XT_SOL_A0, a0 ) /* should be on 16-byte alignment */ - STRUCT_FIELD( long, 4, XT_SOL_A1, a1 ) - STRUCT_FIELD( long, 4, XT_SOL_A2, a2 ) - STRUCT_FIELD( long, 4, XT_SOL_A3, a3 ) -#endif /* ifdef __XTENSA_CALL0_ABI__ */ -STRUCT_END( XtSolFrame ) - -/* Size of solicited stack frame */ -#define XT_SOL_FRMSZ ALIGNUP( 0x10, XtSolFrameSize ) - - -/* - * ------------------------------------------------------------------------------- - * CO-PROCESSOR STATE SAVE AREA FOR A THREAD - * - * The RTOS must provide an area per thread to save the state of co-processors - * when that thread does not have control. Co-processors are context-switched - * lazily (on demand) only when a new thread uses a co-processor instruction, - * otherwise a thread retains ownership of the co-processor even when it loses - * control of the processor. An Xtensa co-processor exception is triggered when - * any co-processor instruction is executed by a thread that is not the owner, - * and the context switch of that co-processor is then peformed by the handler. - * Ownership represents which thread's state is currently in the co-processor. - * - * Co-processors may not be used by interrupt or exception handlers. If an - * co-processor instruction is executed by an interrupt or exception handler, - * the co-processor exception handler will trigger a kernel panic and freeze. - * This restriction is introduced to reduce the overhead of saving and restoring - * co-processor state (which can be quite large) and in particular remove that - * overhead from interrupt handlers. - * - * The co-processor state save area may be in any convenient per-thread location - * such as in the thread control block or above the thread stack area. It need - * not be in the interrupt stack frame since interrupts don't use co-processors. - * - * Along with the save area for each co-processor, two bitmasks with flags per - * co-processor (laid out as in the CPENABLE reg) help manage context-switching - * co-processors as efficiently as possible: - * - * XT_CPENABLE - * The contents of a non-running thread's CPENABLE register. - * It represents the co-processors owned (and whose state is still needed) - * by the thread. When a thread is preempted, its CPENABLE is saved here. - * When a thread solicits a context-swtich, its CPENABLE is cleared - the - * compiler has saved the (caller-saved) co-proc state if it needs to. - * When a non-running thread loses ownership of a CP, its bit is cleared. - * When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg. - * Avoids co-processor exceptions when no change of ownership is needed. - * - * XT_CPSTORED - * A bitmask with the same layout as CPENABLE, a bit per co-processor. - * Indicates whether the state of each co-processor is saved in the state - * save area. When a thread enters the kernel, only the state of co-procs - * still enabled in CPENABLE is saved. When the co-processor exception - * handler assigns ownership of a co-processor to a thread, it restores - * the saved state only if this bit is set, and clears this bit. - * - * XT_CP_CS_ST - * A bitmask with the same layout as CPENABLE, a bit per co-processor. - * Indicates whether callee-saved state is saved in the state save area. - * Callee-saved state is saved by itself on a solicited context switch, - * and restored when needed by the coprocessor exception handler. - * Unsolicited switches will cause the entire coprocessor to be saved - * when necessary. - * - * XT_CP_ASA - * Pointer to the aligned save area. Allows it to be aligned more than - * the overall save area (which might only be stack-aligned or TCB-aligned). - * Especially relevant for Xtensa cores configured with a very large data - * path that requires alignment greater than 16 bytes (ABI stack alignment). - * ------------------------------------------------------------------------------- - */ - -#if XCHAL_CP_NUM > 0 - -/* Offsets of each coprocessor save area within the 'aligned save area': */ -#define XT_CP0_SA 0 -#define XT_CP1_SA ALIGNUP( XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE ) -#define XT_CP2_SA ALIGNUP( XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE ) -#define XT_CP3_SA ALIGNUP( XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE ) -#define XT_CP4_SA ALIGNUP( XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE ) -#define XT_CP5_SA ALIGNUP( XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE ) -#define XT_CP6_SA ALIGNUP( XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE ) -#define XT_CP7_SA ALIGNUP( XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE ) -#define XT_CP_SA_SIZE ALIGNUP( 16, XT_CP7_SA + XCHAL_CP7_SA_SIZE ) - -/* Offsets within the overall save area: */ -#define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */ -#define XT_CPSTORED 2 /* (2 bytes) coprocessors saved for this thread */ -#define XT_CP_CS_ST 4 /* (2 bytes) coprocessor callee-saved regs stored for this thread */ -#define XT_CP_ASA 8 /* (4 bytes) ptr to aligned save area */ -/* Overall size allows for dynamic alignment: */ -#define XT_CP_SIZE ( 12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN ) -#else /* if XCHAL_CP_NUM > 0 */ -#define XT_CP_SIZE 0 -#endif /* if XCHAL_CP_NUM > 0 */ - - -/* - * ------------------------------------------------------------------------------- - * MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN - * - * Convenient where the frame size requirements are the same for both ABIs. - * ENTRY(sz), RET(sz) are for framed functions (have locals or make calls). - * ENTRY0, RET0 are for frameless functions (no locals, no calls). - * - * where size = size of stack frame in bytes (must be >0 and aligned to 16). - * For framed functions the frame is created and the return address saved at - * base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). - * For frameless functions, there is no frame and return address remains in a0. - * Note: Because CPP macros expand to a single line, macros requiring multi-line - * expansions are implemented as assembler macros. - * ------------------------------------------------------------------------------- - */ - -#ifdef __ASSEMBLER__ - #ifdef __XTENSA_CALL0_ABI__ - /* Call0 */ -#define ENTRY( sz ) entry1 sz - .macro entry1 size = 0x10 - addi sp, sp, -\ size - s32i a0, sp, 0 - .endm -#define ENTRY0 -#define RET( sz ) ret1 sz - .macro ret1 size = 0x10 - l32i a0, sp, 0 - addi sp, sp, \ size - ret - .endm -#define RET0 ret - #else /* ifdef __XTENSA_CALL0_ABI__ */ - /* Windowed */ -#define ENTRY( sz ) entry sp, sz -#define ENTRY0 entry sp, 0x10 -#define RET( sz ) retw -#define RET0 retw - #endif /* ifdef __XTENSA_CALL0_ABI__ */ -#endif /* ifdef __ASSEMBLER__ */ - - -#endif /* XTENSA_CONTEXT_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_init.c b/portable/ThirdParty/XCC/Xtensa/xtensa_init.c deleted file mode 100644 index 7ee6f3d63..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_init.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * XTENSA INITIALIZATION ROUTINES CODED IN C - * - * This file contains miscellaneous Xtensa RTOS-generic initialization functions - * that are implemented in C. - */ - - -#ifdef XT_BOARD - #include -#endif - -#include "xtensa_rtos.h" - -#ifdef XT_RTOS_TIMER_INT - - unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */ - -/* - * Compute and initialize at run-time the tick divisor (the number of - * processor clock cycles in an RTOS tick, used to set the tick timer). - * Called when the processor clock frequency is not known at compile-time. - */ - void _xt_tick_divisor_init( void ) - { - #ifdef XT_CLOCK_FREQ - _xt_tick_divisor = ( XT_CLOCK_FREQ / XT_TICK_PER_SEC ); - #else - #ifdef XT_BOARD - _xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC; - #else - #error "No way to obtain processor clock frequency" - #endif /* XT_BOARD */ - #endif /* XT_CLOCK_FREQ */ - } - -#endif /* XT_RTOS_TIMER_INT */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c b/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c deleted file mode 100644 index 87bf63cb4..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Xtensa-specific interrupt and exception functions for RTOS ports. - * Also see xtensa_intr_asm.S. - */ - -#include - -#include - -#include "xtensa_api.h" - - -#if XCHAL_HAVE_EXCEPTIONS - -/* Handler table is in xtensa_intr_asm.S */ - - extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM ]; - - -/* - * Default handler for unhandled exceptions. - */ - void xt_unhandled_exception( XtExcFrame * frame ) - { - exit( -1 ); - } - - -/* - * This function registers a handler for the specified exception. - * The function returns the address of the previous handler. - * On error, it returns 0. - */ - xt_exc_handler xt_set_exception_handler( int n, - xt_exc_handler f ) - { - xt_exc_handler old; - - if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) ) - { - return 0; /* invalid exception number */ - } - - old = _xt_exception_table[ n ]; - - if( f ) - { - _xt_exception_table[ n ] = f; - } - else - { - _xt_exception_table[ n ] = &xt_unhandled_exception; - } - - return( ( old == &xt_unhandled_exception ) ? 0 : old ); - } - -#endif /* if XCHAL_HAVE_EXCEPTIONS */ - -#if XCHAL_HAVE_INTERRUPTS - -/* Handler table is in xtensa_intr_asm.S */ - - typedef struct xt_handler_table_entry - { - void * handler; - void * arg; - } xt_handler_table_entry; - - extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS ]; - - -/* - * Default handler for unhandled interrupts. - */ - void xt_unhandled_interrupt( void * arg ) - { - exit( -1 ); - } - - -/* - * This function registers a handler for the specified interrupt. The "arg" - * parameter specifies the argument to be passed to the handler when it is - * invoked. The function returns the address of the previous handler. - * On error, it returns 0. - */ - xt_handler xt_set_interrupt_handler( int n, - xt_handler f, - void * arg ) - { - xt_handler_table_entry * entry; - xt_handler old; - - if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) ) - { - return 0; /* invalid interrupt number */ - } - - if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL ) - { - return 0; /* priority level too high to safely handle in C */ - } - - entry = _xt_interrupt_table + n; - old = entry->handler; - - if( f ) - { - entry->handler = f; - entry->arg = arg; - } - else - { - entry->handler = &xt_unhandled_interrupt; - entry->arg = ( void * ) n; - } - - return( ( old == &xt_unhandled_interrupt ) ? 0 : old ); - } - - -#endif /* XCHAL_HAVE_INTERRUPTS */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_intr_asm.S b/portable/ThirdParty/XCC/Xtensa/xtensa_intr_asm.S deleted file mode 100644 index ec5ac4c83..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_intr_asm.S +++ /dev/null @@ -1,183 +0,0 @@ - /* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Xtensa interrupt handling data and assembly routines. - * Also see xtensa_intr.c and xtensa_vectors.S. - */ - -#include -#include - -#include "xtensa_context.h" - -#if XCHAL_HAVE_INTERRUPTS - -/* -------------------------------------------------------------------------------- - INTENABLE virtualization information. -------------------------------------------------------------------------------- -*/ - - .data - .global _xt_intdata - .align 8 -_xt_intdata: - .global _xt_intenable - .type _xt_intenable,@object - .size _xt_intenable,4 - .global _xt_vpri_mask - .type _xt_vpri_mask,@object - .size _xt_vpri_mask,4 - -_xt_intenable: .word 0 /* Virtual INTENABLE */ -_xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */ - - -/* -------------------------------------------------------------------------------- - Table of C-callable interrupt handlers for each interrupt. Note that not all - slots can be filled, because interrupts at level > EXCM_LEVEL will not be - dispatched to a C handler by default. -------------------------------------------------------------------------------- -*/ - - .data - .global _xt_interrupt_table - .align 8 - -_xt_interrupt_table: - - .set i, 0 - .rept XCHAL_NUM_INTERRUPTS - .word xt_unhandled_interrupt /* handler address */ - .word i /* handler arg (default: intnum) */ - .set i, i+1 - .endr - -#endif /* XCHAL_HAVE_INTERRUPTS */ - - -#if XCHAL_HAVE_EXCEPTIONS - -/* -------------------------------------------------------------------------------- - Table of C-callable exception handlers for each exception. Note that not all - slots will be active, because some exceptions (e.g. coprocessor exceptions) - are always handled by the OS and cannot be hooked by user handlers. -------------------------------------------------------------------------------- -*/ - - .data - .global _xt_exception_table - .align 4 - -_xt_exception_table: - .rept XCHAL_EXCCAUSE_NUM - .word xt_unhandled_exception /* handler address */ - .endr - -#endif - - -/* -------------------------------------------------------------------------------- - unsigned int xt_ints_on ( unsigned int mask ) - - Enables a set of interrupts. Does not simply set INTENABLE directly, but - computes it as a function of the current virtual priority. - Can be called from interrupt handlers. -------------------------------------------------------------------------------- -*/ - - .text - .align 4 - .global xt_ints_on - .type xt_ints_on,@function - -xt_ints_on: - - ENTRY0 -#if XCHAL_HAVE_INTERRUPTS - movi a3, 0 - movi a4, _xt_intdata - xsr a3, INTENABLE /* Disables all interrupts */ - rsync - l32i a3, a4, 0 /* a3 = _xt_intenable */ - l32i a6, a4, 4 /* a6 = _xt_vpri_mask */ - or a5, a3, a2 /* a5 = _xt_intenable | mask */ - s32i a5, a4, 0 /* _xt_intenable |= mask */ - and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */ - wsr a5, INTENABLE /* Reenable interrupts */ - mov a2, a3 /* Previous mask */ -#else - movi a2, 0 /* Return zero */ -#endif - RET0 - - .size xt_ints_on, . - xt_ints_on - - -/* -------------------------------------------------------------------------------- - unsigned int xt_ints_off ( unsigned int mask ) - - Disables a set of interrupts. Does not simply set INTENABLE directly, - but computes it as a function of the current virtual priority. - Can be called from interrupt handlers. -------------------------------------------------------------------------------- -*/ - - .text - .align 4 - .global xt_ints_off - .type xt_ints_off,@function - -xt_ints_off: - - ENTRY0 -#if XCHAL_HAVE_INTERRUPTS - movi a3, 0 - movi a4, _xt_intdata - xsr a3, INTENABLE /* Disables all interrupts */ - rsync - l32i a3, a4, 0 /* a3 = _xt_intenable */ - l32i a6, a4, 4 /* a6 = _xt_vpri_mask */ - or a5, a3, a2 /* a5 = _xt_intenable | mask */ - xor a5, a5, a2 /* a5 = _xt_intenable & ~mask */ - s32i a5, a4, 0 /* _xt_intenable &= ~mask */ - and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */ - wsr a5, INTENABLE /* Reenable interrupts */ - mov a2, a3 /* Previous mask */ -#else - movi a2, 0 /* return zero */ -#endif - RET0 - - .size xt_ints_off, . - xt_ints_off diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c b/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c deleted file mode 100644 index fcbc57386..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * xtensa_overlay_os_hook.c -- Overlay manager OS hooks for FreeRTOS. - */ - -#include "FreeRTOS.h" -#include "semphr.h" - -#if configUSE_MUTEX - -/* Mutex object that controls access to the overlay. Currently only one - * overlay region is supported so one mutex suffices. - */ - static SemaphoreHandle_t xt_overlay_mutex; - - -/* This function should be overridden to provide OS specific init such - * as the creation of a mutex lock that can be used for overlay locking. - * Typically this mutex would be set up with priority inheritance. See - * overlay manager documentation for more details. - */ - void xt_overlay_init_os( void ) - { - /* Create the mutex for overlay access. Priority inheritance is - * required. - */ - xt_overlay_mutex = xSemaphoreCreateMutex(); - } - - -/* This function locks access to shared overlay resources, typically - * by acquiring a mutex. - */ - void xt_overlay_lock( void ) - { - xSemaphoreTake( xt_overlay_mutex, 0 ); - } - - -/* This function releases access to shared overlay resources, typically - * by unlocking a mutex. - */ - void xt_overlay_unlock( void ) - { - xSemaphoreGive( xt_overlay_mutex ); - } - -#endif /* if configUSE_MUTEX */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h b/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h deleted file mode 100644 index 54f4d0b7e..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES - * (FreeRTOS Port) - * - * This header is the primary glue between generic Xtensa RTOS support - * sources and a specific RTOS port for Xtensa. It contains definitions - * and macros for use primarily by Xtensa assembly coded source files. - * - * Macros in this header map callouts from generic Xtensa files to specific - * RTOS functions. It may also be included in C source files. - * - * Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa - * architecture, using the Xtensa hardware abstraction layer (HAL) to deal - * with configuration specifics. - * - * Should be included by all Xtensa generic and RTOS port-specific sources. - */ - -#ifndef XTENSA_RTOS_H -#define XTENSA_RTOS_H - -#ifdef __ASSEMBLER__ - #include -#else - #include -#endif - -#include -#include -#include - -/* - * Include any RTOS specific definitions that are needed by this header. - */ -#include - -/* - * Convert FreeRTOSConfig definitions to XTENSA definitions. - * However these can still be overridden from the command line. - */ - -#ifndef XT_SIMULATOR - #if configXT_SIMULATOR - #define XT_SIMULATOR 1 /* Simulator mode */ - #endif -#endif - -#ifndef XT_BOARD - #if configXT_BOARD - #define XT_BOARD 1 /* Board mode */ - #endif -#endif - -#ifndef XT_TIMER_INDEX - #if defined configXT_TIMER_INDEX - #define XT_TIMER_INDEX configXT_TIMER_INDEX /* Index of hardware timer to be used */ - #endif -#endif - -#ifndef XT_INTEXC_HOOKS - #if configXT_INTEXC_HOOKS - #define XT_INTEXC_HOOKS 1 /* Enables exception hooks */ - #endif -#endif - -#if ( !XT_SIMULATOR ) && ( !XT_BOARD ) - #error Either XT_SIMULATOR or XT_BOARD must be defined. -#endif - - -/* - * Name of RTOS (for messages). - */ -#define XT_RTOS_NAME FreeRTOS - -/* - * Check some Xtensa configuration requirements and report error if not met. - * Error messages can be customize to the RTOS port. - */ - -#if !XCHAL_HAVE_XEA2 - #error "FreeRTOS/Xtensa requires XEA2 (exception architecture 2)." -#endif - - -/******************************************************************************* -* -* RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS. -* -* Define callout macros used in generic Xtensa code to interact with the RTOS. -* The macros are simply the function names for use in calls from assembler code. -* Some of these functions may call back to generic functions in xtensa_context.h . -* -*******************************************************************************/ - -/* - * Inform RTOS of entry into an interrupt handler that will affect it. - * Allows RTOS to manage switch to any system stack and count nesting level. - * Called after minimal context has been saved, with interrupts disabled. - * RTOS port can call0 _xt_context_save to save the rest of the context. - * May only be called from assembly code by the 'call0' instruction. - */ -/* void XT_RTOS_INT_ENTER(void) */ -#define XT_RTOS_INT_ENTER _frxt_int_enter - -/* - * Inform RTOS of completion of an interrupt handler, and give control to - * RTOS to perform thread/task scheduling, switch back from any system stack - * and restore the context, and return to the exit dispatcher saved in the - * stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore - * to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save, - * leaving only a minimal part of the context to be restored by the exit - * dispatcher. This function does not return to the place it was called from. - * May only be called from assembly code by the 'call0' instruction. - */ -/* void XT_RTOS_INT_EXIT(void) */ -#define XT_RTOS_INT_EXIT _frxt_int_exit - -/* - * Inform RTOS of the occurrence of a tick timer interrupt. - * If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined. - * May be coded in or called from C or assembly, per ABI conventions. - * RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro). - */ -/* void XT_RTOS_TIMER_INT(void) */ -#define XT_RTOS_TIMER_INT _frxt_timer_int -#define XT_TICK_PER_SEC configTICK_RATE_HZ - -/* - * Return in a15 the base address of the co-processor state save area for the - * thread that triggered a co-processor exception, or 0 if no thread was running. - * The state save area is structured as defined in xtensa_context.h and has size - * XT_CP_SIZE. Co-processor instructions should only be used in thread code, never - * in interrupt handlers or the RTOS kernel. May only be called from assembly code - * and by the 'call0' instruction. A result of 0 indicates an unrecoverable error. - * The implementation may use only a2-4, a15 (all other regs must be preserved). - */ -/* void* XT_RTOS_CP_STATE(void) */ -#define XT_RTOS_CP_STATE _frxt_task_coproc_state - - -/******************************************************************************* -* -* HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL. -* -* This Xtensa RTOS port provides hooks for dynamically installing exception -* and interrupt handlers to facilitate automated testing where each test -* case can install its own handler for user exceptions and each interrupt -* priority (level). This consists of an array of function pointers indexed -* by interrupt priority, with index 0 being the user exception handler hook. -* Each entry in the array is initially 0, and may be replaced by a function -* pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0. -* -* The handler for low and medium priority obeys ABI conventions so may be coded -* in C. For the exception handler, the cause is the contents of the EXCCAUSE -* reg, and the result is -1 if handled, else the cause (still needs handling). -* For interrupt handlers, the cause is a mask of pending enabled interrupts at -* that level, and the result is the same mask with the bits for the handled -* interrupts cleared (those not cleared still need handling). This allows a test -* case to either pre-handle or override the default handling for the exception -* or interrupt level (see xtensa_vectors.S). -* -* High priority handlers (including NMI) must be coded in assembly, are always -* called by 'call0' regardless of ABI, must preserve all registers except a0, -* and must not use or modify the interrupted stack. The hook argument 'cause' -* is not passed and the result is ignored, so as not to burden the caller with -* saving and restoring a2 (it assumes only one interrupt per level - see the -* discussion in high priority interrupts in xtensa_vectors.S). The handler -* therefore should be coded to prototype 'void h(void)' even though it plugs -* into an array of handlers of prototype 'unsigned h(unsigned)'. -* -* To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'. -* -*******************************************************************************/ - -#define XT_INTEXC_HOOK_NUM ( 1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI ) - -#ifndef __ASSEMBLER__ - typedef unsigned (* XT_INTEXC_HOOK)( unsigned cause ); - extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[ XT_INTEXC_HOOK_NUM ]; -#endif - - -/******************************************************************************* -* -* CONVENIENCE INCLUSIONS. -* -* Ensures RTOS specific files need only include this one Xtensa-generic header. -* These headers are included last so they can use the RTOS definitions above. -* -*******************************************************************************/ - -#include "xtensa_context.h" - -#ifdef XT_RTOS_TIMER_INT - #include "xtensa_timer.h" -#endif - - -/******************************************************************************* -* -* Xtensa Port Version. -* -*******************************************************************************/ - -#define XTENSA_PORT_VERSION 1.7 -#define XTENSA_PORT_VERSION_STRING "1.7" - -#endif /* XTENSA_RTOS_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h b/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h deleted file mode 100644 index ecaf3f4e9..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY - * - * This header contains definitions and macros for use primarily by Xtensa - * RTOS assembly coded source files. It includes and uses the Xtensa hardware - * abstraction layer (HAL) to deal with config specifics. It may also be - * included in C source files. - * - * Edit this file to modify timer selection and to specify clock frequency and - * tick duration to match timer interrupt to the real-time tick duration. - * - * If the RTOS has no timer interrupt, then there is no tick timer and the - * clock frequency is irrelevant, so all of these macros are left undefined - * and the Xtensa core configuration need not have a timer. - */ - -#ifndef XTENSA_TIMER_H -#define XTENSA_TIMER_H - -#ifdef __ASSEMBLER__ - #include -#endif - -#include -#include - -#include "xtensa_rtos.h" /* in case this wasn't included directly */ - -#include - -/* - * Select timer to use for periodic tick, and determine its interrupt number - * and priority. User may specify a timer by defining XT_TIMER_INDEX with -D, - * in which case its validity is checked (it must exist in this core and must - * not be on a high priority interrupt - an error will be reported in invalid). - * Otherwise select the first low or medium priority interrupt timer available. - */ -#if XCHAL_NUM_TIMERS == 0 - - #error "This Xtensa configuration is unsupported, it has no timers." - -#else - - #ifndef XT_TIMER_INDEX - #if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER3_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 3 - #endif - #endif - #if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER2_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 2 - #endif - #endif - #if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER1_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 1 - #endif - #endif - #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER0_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 0 - #endif - #endif - #endif /* ifndef XT_TIMER_INDEX */ - #ifndef XT_TIMER_INDEX - #error "There is no suitable timer in this Xtensa configuration." - #endif - - #define XT_CCOMPARE ( CCOMPARE + XT_TIMER_INDEX ) - #define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT( XT_TIMER_INDEX ) - #define XT_TIMER_INTPRI XCHAL_INT_LEVEL( XT_TIMER_INTNUM ) - #define XT_TIMER_INTEN ( 1 << XT_TIMER_INTNUM ) - - #if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED - #error "The timer selected by XT_TIMER_INDEX does not exist in this core." - #elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL - #error "The timer interrupt cannot be high priority (use medium or low)." - #endif - -#endif /* XCHAL_NUM_TIMERS */ - -/* - * Set processor clock frequency, used to determine clock divisor for timer tick. - * User should BE SURE TO ADJUST THIS for the Xtensa platform being used. - * If using a supported board via the board-independent API defined in xtbsp.h, - * this may be left undefined and frequency and tick divisor will be computed - * and cached during run-time initialization. - * - * NOTE ON SIMULATOR: - * Under the Xtensa instruction set simulator, the frequency can only be estimated - * because it depends on the speed of the host and the version of the simulator. - * Also because it runs much slower than hardware, it is not possible to achieve - * real-time performance for most applications under the simulator. A frequency - * too low does not allow enough time between timer interrupts, starving threads. - * To obtain a more convenient but non-real-time tick duration on the simulator, - * compile with xt-xcc option "-DXT_SIMULATOR". - * Adjust this frequency to taste (it's not real-time anyway!). - */ -#if defined( XT_SIMULATOR ) && !defined( XT_CLOCK_FREQ ) - #define XT_CLOCK_FREQ configCPU_CLOCK_HZ -#endif - -#if !defined( XT_CLOCK_FREQ ) && !defined( XT_BOARD ) - #error "XT_CLOCK_FREQ must be defined for the target platform." -#endif - -/* - * Default number of timer "ticks" per second (default 100 for 10ms tick). - * RTOS may define this in its own way (if applicable) in xtensa_rtos.h. - * User may redefine this to an optimal value for the application, either by - * editing this here or in xtensa_rtos.h, or compiling with xt-xcc option - * "-DXT_TICK_PER_SEC=" where is a suitable number. - */ -#ifndef XT_TICK_PER_SEC - #define XT_TICK_PER_SEC configTICK_RATE_HZ /* 10 ms tick = 100 ticks per second */ -#endif - -/* - * Derivation of clock divisor for timer tick and interrupt (one per tick). - */ -#ifdef XT_CLOCK_FREQ - #define XT_TICK_DIVISOR ( XT_CLOCK_FREQ / XT_TICK_PER_SEC ) -#endif - -#ifndef __ASSEMBLER__ - extern unsigned _xt_tick_divisor; - extern void _xt_tick_divisor_init( void ); -#endif - -#endif /* XTENSA_TIMER_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_vectors.S b/portable/ThirdParty/XCC/Xtensa/xtensa_vectors.S deleted file mode 100644 index 7b8e9fd58..000000000 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_vectors.S +++ /dev/null @@ -1,1924 +0,0 @@ - /* - * FreeRTOS Kernel - * Copyright (C) 2015-2019 Cadence Design Systems, Inc. - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - XTENSA VECTORS AND LOW LEVEL HANDLERS FOR AN RTOS - - Xtensa low level exception and interrupt vectors and handlers for an RTOS. - - Interrupt handlers and user exception handlers support interaction with - the RTOS by calling XT_RTOS_INT_ENTER and XT_RTOS_INT_EXIT before and - after user's specific interrupt handlers. These macros are defined in - xtensa_.h to call suitable functions in a specific RTOS. - - Users can install application-specific interrupt handlers for low and - medium level interrupts, by calling xt_set_interrupt_handler(). These - handlers can be written in C, and must obey C calling convention. The - handler table is indexed by the interrupt number. Each handler may be - provided with an argument. - - Note that the system timer interrupt is handled specially, and is - dispatched to the RTOS-specific handler. This timer cannot be hooked - by application code. - - Optional hooks are also provided to install a handler per level at - run-time, made available by compiling this source file with - '-DXT_INTEXC_HOOKS' (useful for automated testing). - -!! This file is a template that usually needs to be modified to handle !! -!! application specific interrupts. Search USER_EDIT for helpful comments !! -!! on where to insert handlers and how to write them. !! - - Users can also install application-specific exception handlers in the - same way, by calling xt_set_exception_handler(). One handler slot is - provided for each exception type. Note that some exceptions are handled - by the porting layer itself, and cannot be taken over by application - code in this manner. These are the alloca, syscall, and coprocessor - exceptions. - - The exception handlers can be written in C, and must follow C calling - convention. Each handler is passed a pointer to an exception frame as - its single argument. The exception frame is created on the stack, and - holds the saved context of the thread that took the exception. If the - handler returns, the context will be restored and the instruction that - caused the exception will be retried. If the handler makes any changes - to the saved state in the exception frame, the changes will be applied - when restoring the context. - - Because Xtensa is a configurable architecture, this port supports all user - generated configurations (except restrictions stated in the release notes). - This is accomplished by conditional compilation using macros and functions - defined in the Xtensa HAL (hardware adaptation layer) for your configuration. - Only the relevant parts of this file will be included in your RTOS build. - For example, this file provides interrupt vector templates for all types and - all priority levels, but only the ones in your configuration are built. - - NOTES on the use of 'call0' for long jumps instead of 'j': - 1. This file should be assembled with the -mlongcalls option to xt-xcc. - 2. The -mlongcalls compiler option causes 'call0 dest' to be expanded to - a sequence 'l32r a0, dest' 'callx0 a0' which works regardless of the - distance from the call to the destination. The linker then relaxes - it back to 'call0 dest' if it determines that dest is within range. - This allows more flexibility in locating code without the performance - overhead of the 'l32r' literal data load in cases where the destination - is in range of 'call0'. There is an additional benefit in that 'call0' - has a longer range than 'j' due to the target being word-aligned, so - the 'l32r' sequence is less likely needed. - 3. The use of 'call0' with -mlongcalls requires that register a0 not be - live at the time of the call, which is always the case for a function - call but needs to be ensured if 'call0' is used as a jump in lieu of 'j'. - 4. This use of 'call0' is independent of the C function call ABI. - - */ - -#include "xtensa_rtos.h" - - -/* Enable stack backtrace across exception/interrupt - see below */ -#define XT_DEBUG_BACKTRACE 1 - - -/* --------------------------------------------------------------------------------- - Defines used to access _xtos_interrupt_table. --------------------------------------------------------------------------------- -*/ -#define XIE_HANDLER 0 -#define XIE_ARG 4 -#define XIE_SIZE 8 - -/* --------------------------------------------------------------------------------- - Macro extract_msb - return the input with only the highest bit set. - - Input : "ain" - Input value, clobbered. - Output : "aout" - Output value, has only one bit set, MSB of "ain". - The two arguments must be different AR registers. --------------------------------------------------------------------------------- -*/ - - .macro extract_msb aout ain -1: - addi \aout, \ain, -1 /* aout = ain - 1 */ - and \ain, \ain, \aout /* ain = ain & aout */ - bnez \ain, 1b /* repeat until ain == 0 */ - addi \aout, \aout, 1 /* return aout + 1 */ - .endm - -/* --------------------------------------------------------------------------------- - Macro dispatch_c_isr - dispatch interrupts to user ISRs. - This will dispatch to user handlers (if any) that are registered in the - XTOS dispatch table (_xtos_interrupt_table). These handlers would have - been registered by calling _xtos_set_interrupt_handler(). There is one - exception - the timer interrupt used by the OS will not be dispatched - to a user handler - this must be handled by the caller of this macro. - - Level triggered and software interrupts are automatically deasserted by - this code. - - ASSUMPTIONS: - -- PS.INTLEVEL is set to "level" at entry - -- PS.EXCM = 0, C calling enabled - - NOTE: For CALL0 ABI, a12-a15 have not yet been saved. - - NOTE: This macro will use registers a0 and a2-a6. The arguments are: - level -- interrupt level - mask -- interrupt bitmask for this level --------------------------------------------------------------------------------- -*/ - - .macro dispatch_c_isr level mask - - /* Get mask of pending, enabled interrupts at this level into a2. */ - -.L_xt_user_int_&level&: - rsr a2, INTENABLE - rsr a3, INTERRUPT - movi a4, \mask - and a2, a2, a3 - and a2, a2, a4 - beqz a2, 9f /* nothing to do */ - - /* This bit of code provides a nice debug backtrace in the debugger. - It does take a few more instructions, so undef XT_DEBUG_BACKTRACE - if you want to save the cycles. - */ - #if XT_DEBUG_BACKTRACE - #ifndef __XTENSA_CALL0_ABI__ - rsr a0, EPC_1 + \level - 1 /* return address */ - movi a4, 0xC0000000 /* constant with top 2 bits set (call size) */ - or a0, a0, a4 /* set top 2 bits */ - addx2 a0, a4, a0 /* clear top bit -- simulating call4 size */ - #endif - #endif - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a4, _xt_intexc_hooks - l32i a4, a4, \level << 2 - beqz a4, 2f - #ifdef __XTENSA_CALL0_ABI__ - callx0 a4 - beqz a2, 9f - #else - mov a6, a2 - callx4 a4 - beqz a6, 9f - mov a2, a6 - #endif -2: - #endif - - /* Now look up in the dispatch table and call user ISR if any. */ - /* If multiple bits are set then MSB has highest priority. */ - - extract_msb a4, a2 /* a4 = MSB of a2, a2 trashed */ - - #ifdef XT_USE_SWPRI - /* Enable all interrupts at this level that are numerically higher - than the one we just selected, since they are treated as higher - priority. - */ - movi a3, \mask /* a3 = all interrupts at this level */ - add a2, a4, a4 /* a2 = a4 << 1 */ - addi a2, a2, -1 /* a2 = mask of 1's <= a4 bit */ - and a2, a2, a3 /* a2 = mask of all bits <= a4 at this level */ - movi a3, _xt_intdata - l32i a6, a3, 4 /* a6 = _xt_vpri_mask */ - neg a2, a2 - addi a2, a2, -1 /* a2 = mask to apply */ - and a5, a6, a2 /* mask off all bits <= a4 bit */ - s32i a5, a3, 4 /* update _xt_vpri_mask */ - rsr a3, INTENABLE - and a3, a3, a2 /* mask off all bits <= a4 bit */ - wsr a3, INTENABLE - rsil a3, \level - 1 /* lower interrupt level by 1 */ - #endif - - movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */ - wsr a4, INTCLEAR /* clear sw or edge-triggered interrupt */ - beq a3, a4, 7f /* if timer interrupt then skip table */ - - find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */ - - movi a4, _xt_interrupt_table - addx8 a3, a3, a4 /* a3 = address of interrupt table entry */ - l32i a4, a3, XIE_HANDLER /* a4 = handler address */ - #ifdef __XTENSA_CALL0_ABI__ - mov a12, a6 /* save in callee-saved reg */ - l32i a2, a3, XIE_ARG /* a2 = handler arg */ - callx0 a4 /* call handler */ - mov a2, a12 - #else - mov a2, a6 /* save in windowed reg */ - l32i a6, a3, XIE_ARG /* a6 = handler arg */ - callx4 a4 /* call handler */ - #endif - - #ifdef XT_USE_SWPRI - j 8f - #else - j .L_xt_user_int_&level& /* check for more interrupts */ - #endif - -7: - - .ifeq XT_TIMER_INTPRI - \level -.L_xt_user_int_timer_&level&: - /* - Interrupt handler for the RTOS tick timer if at this level. - We'll be reading the interrupt state again after this call - so no need to preserve any registers except a6 (vpri_mask). - */ - - #ifdef __XTENSA_CALL0_ABI__ - mov a12, a6 - call0 XT_RTOS_TIMER_INT - mov a2, a12 - #else - mov a2, a6 - call4 XT_RTOS_TIMER_INT - #endif - .endif - - #ifdef XT_USE_SWPRI - j 8f - #else - j .L_xt_user_int_&level& /* check for more interrupts */ - #endif - - #ifdef XT_USE_SWPRI -8: - /* Restore old value of _xt_vpri_mask from a2. Also update INTENABLE from - virtual _xt_intenable which _could_ have changed during interrupt - processing. */ - - movi a3, _xt_intdata - l32i a4, a3, 0 /* a4 = _xt_intenable */ - s32i a2, a3, 4 /* update _xt_vpri_mask */ - and a4, a4, a2 /* a4 = masked intenable */ - wsr a4, INTENABLE /* update INTENABLE */ - #endif - -9: - /* done */ - - .endm - - -/* --------------------------------------------------------------------------------- - Panic handler. - Should be reached by call0 (preferable) or jump only. If call0, a0 says where - from. If on simulator, display panic message and abort, else loop indefinitely. --------------------------------------------------------------------------------- -*/ - - .text - .global _xt_panic - .type _xt_panic,@function - .align 4 - .literal_position - -_xt_panic: - #ifdef XT_SIMULATOR - addi a4, a0, -3 /* point to call0 */ - movi a3, _xt_panic_message - movi a2, SYS_log_msg - simcall - movi a2, SYS_gdb_abort - simcall - #else - rsil a2, XCHAL_EXCM_LEVEL /* disable all low & med ints */ -1: j 1b /* loop infinitely */ - #endif - - .section .rodata, "a" - .align 4 - -_xt_panic_message: - .string "\n*** _xt_panic() was called from 0x%08x or jumped to. ***\n" - - -/* --------------------------------------------------------------------------------- - Hooks to dynamically install handlers for exceptions and interrupts. - Allows automated regression frameworks to install handlers per test. - Consists of an array of function pointers indexed by interrupt level, - with index 0 containing the entry for user exceptions. - Initialized with all 0s, meaning no handler is installed at each level. - See comment in xtensa_rtos.h for more details. --------------------------------------------------------------------------------- -*/ - - #ifdef XT_INTEXC_HOOKS - .data - .global _xt_intexc_hooks - .type _xt_intexc_hooks,@object - .align 4 - -_xt_intexc_hooks: - .fill XT_INTEXC_HOOK_NUM, 4, 0 - #endif - - -/* --------------------------------------------------------------------------------- - EXCEPTION AND LEVEL 1 INTERRUPT VECTORS AND LOW LEVEL HANDLERS - (except window exception vectors). - - Each vector goes at a predetermined location according to the Xtensa - hardware configuration, which is ensured by its placement in a special - section known to the Xtensa linker support package (LSP). It performs - the minimum necessary before jumping to the handler in the .text section. - - The corresponding handler goes in the normal .text section. It sets up - the appropriate stack frame, saves a few vector-specific registers and - calls XT_RTOS_INT_ENTER to save the rest of the interrupted context - and enter the RTOS, then sets up a C environment. It then calls the - user's interrupt handler code (which may be coded in C) and finally - calls XT_RTOS_INT_EXIT to transfer control to the RTOS for scheduling. - - While XT_RTOS_INT_EXIT does not return directly to the interruptee, - eventually the RTOS scheduler will want to dispatch the interrupted - task or handler. The scheduler will return to the exit point that was - saved in the interrupt stack frame at XT_STK_EXIT. --------------------------------------------------------------------------------- -*/ - - -/* --------------------------------------------------------------------------------- -Debug Exception. --------------------------------------------------------------------------------- -*/ - -#if XCHAL_HAVE_DEBUG - - .begin literal_prefix .DebugExceptionVector - .section .DebugExceptionVector.text, "ax" - .global _DebugExceptionVector - .align 4 - .literal_position - -_DebugExceptionVector: - - #ifdef XT_SIMULATOR - /* - In the simulator, let the debugger (if any) handle the debug exception, - or simply stop the simulation: - */ - wsr a2, EXCSAVE+XCHAL_DEBUGLEVEL /* save a2 where sim expects it */ - movi a2, SYS_gdb_enter_sktloop - simcall /* have ISS handle debug exc. */ - #elif 0 /* change condition to 1 to use the HAL minimal debug handler */ - wsr a3, EXCSAVE+XCHAL_DEBUGLEVEL - movi a3, xthal_debugexc_defhndlr_nw /* use default debug handler */ - jx a3 - #else - wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */ - call0 _xt_panic /* does not return */ - rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */ - #endif - - .end literal_prefix - -#endif - -/* --------------------------------------------------------------------------------- -Double Exception. -Double exceptions are not a normal occurrence. They indicate a bug of some kind. --------------------------------------------------------------------------------- -*/ - -#ifdef XCHAL_DOUBLEEXC_VECTOR_VADDR - - .begin literal_prefix .DoubleExceptionVector - .section .DoubleExceptionVector.text, "ax" - .global _DoubleExceptionVector - .align 4 - .literal_position - -_DoubleExceptionVector: - - #if XCHAL_HAVE_DEBUG - break 1, 4 /* unhandled double exception */ - #endif - call0 _xt_panic /* does not return */ - rfde /* make a0 point here not later */ - - .end literal_prefix - -#endif /* XCHAL_DOUBLEEXC_VECTOR_VADDR */ - -/* --------------------------------------------------------------------------------- -Kernel Exception (including Level 1 Interrupt from kernel mode). --------------------------------------------------------------------------------- -*/ - - .begin literal_prefix .KernelExceptionVector - .section .KernelExceptionVector.text, "ax" - .global _KernelExceptionVector - .align 4 - .literal_position - -_KernelExceptionVector: - - wsr a0, EXCSAVE_1 /* preserve a0 */ - call0 _xt_kernel_exc /* kernel exception handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .align 4 - -_xt_kernel_exc: - #if XCHAL_HAVE_DEBUG - break 1, 0 /* unhandled kernel exception */ - #endif - call0 _xt_panic /* does not return */ - rfe /* make a0 point here not there */ - - -/* --------------------------------------------------------------------------------- -User Exception (including Level 1 Interrupt from user mode). --------------------------------------------------------------------------------- -*/ - - .begin literal_prefix .UserExceptionVector - .section .UserExceptionVector.text, "ax" - .global _UserExceptionVector - .type _UserExceptionVector,@function - .align 4 - .literal_position - -_UserExceptionVector: - - wsr a0, EXCSAVE_1 /* preserve a0 */ - call0 _xt_user_exc /* user exception handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - -/* --------------------------------------------------------------------------------- - Insert some waypoints for jumping beyond the signed 8-bit range of - conditional branch instructions, so the conditional branchces to specific - exception handlers are not taken in the mainline. Saves some cycles in the - mainline. --------------------------------------------------------------------------------- -*/ - - .text - - #if XCHAL_HAVE_WINDOWED - .align 4 -_xt_to_alloca_exc: - call0 _xt_alloca_exc /* in window vectors section */ - /* never returns here - call0 is used as a jump (see note at top) */ - #endif - - .align 4 -_xt_to_syscall_exc: - call0 _xt_syscall_exc - /* never returns here - call0 is used as a jump (see note at top) */ - - #if XCHAL_CP_NUM > 0 - .align 4 -_xt_to_coproc_exc: - call0 _xt_coproc_exc - /* never returns here - call0 is used as a jump (see note at top) */ - #endif - - -/* --------------------------------------------------------------------------------- - User exception handler. --------------------------------------------------------------------------------- -*/ - - .type _xt_user_exc,@function - .align 4 - -_xt_user_exc: - - /* If level 1 interrupt then jump to the dispatcher */ - rsr a0, EXCCAUSE - beqi a0, EXCCAUSE_LEVEL1INTERRUPT, _xt_lowint1 - - /* Handle any coprocessor exceptions. Rely on the fact that exception - numbers above EXCCAUSE_CP0_DISABLED all relate to the coprocessors. - */ - #if XCHAL_CP_NUM > 0 - bgeui a0, EXCCAUSE_CP0_DISABLED, _xt_to_coproc_exc - #endif - - /* Handle alloca and syscall exceptions */ - #if XCHAL_HAVE_WINDOWED - beqi a0, EXCCAUSE_ALLOCA, _xt_to_alloca_exc - #endif - beqi a0, EXCCAUSE_SYSCALL, _xt_to_syscall_exc - - /* Handle all other exceptions. All can have user-defined handlers. */ - /* NOTE: we'll stay on the user stack for exception handling. */ - - /* Allocate exception frame and save minimal context. */ - mov a0, sp - addi sp, sp, -XT_STK_FRMSZ - s32i a0, sp, XT_STK_A1 - #if XCHAL_HAVE_WINDOWED - s32e a0, sp, -12 /* for debug backtrace */ - #endif - rsr a0, PS /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_1 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_1 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - #if XCHAL_HAVE_WINDOWED - s32e a0, sp, -16 /* for debug backtrace */ - #endif - s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ - s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ - call0 _xt_context_save - - /* Save exc cause and vaddr into exception frame */ - rsr a0, EXCCAUSE - s32i a0, sp, XT_STK_EXCCAUSE - rsr a0, EXCVADDR - s32i a0, sp, XT_STK_EXCVADDR - - /* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM - #else - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE - #endif - wsr a0, PS - - #ifdef XT_DEBUG_BACKTRACE - #ifndef __XTENSA_CALL0_ABI__ - rsr a0, EPC_1 /* return address for debug backtrace */ - movi a5, 0xC0000000 /* constant with top 2 bits set (call size) */ - rsync /* wait for WSR.PS to complete */ - or a0, a0, a5 /* set top 2 bits */ - addx2 a0, a5, a0 /* clear top bit -- thus simulating call4 size */ - #else - rsync /* wait for WSR.PS to complete */ - #endif - #endif - - rsr a2, EXCCAUSE /* recover exc cause */ - - #ifdef XT_INTEXC_HOOKS - /* - Call exception hook to pre-handle exceptions (if installed). - Pass EXCCAUSE in a2, and check result in a2 (if -1, skip default handling). - */ - movi a4, _xt_intexc_hooks - l32i a4, a4, 0 /* user exception hook index 0 */ - beqz a4, 1f -.Ln_xt_user_exc_call_hook: - #ifdef __XTENSA_CALL0_ABI__ - callx0 a4 - beqi a2, -1, .L_xt_user_done - #else - mov a6, a2 - callx4 a4 - beqi a6, -1, .L_xt_user_done - mov a2, a6 - #endif -1: - #endif - - rsr a2, EXCCAUSE /* recover exc cause */ - movi a3, _xt_exception_table - addx4 a4, a2, a3 /* a4 = address of exception table entry */ - l32i a4, a4, 0 /* a4 = handler address */ - #ifdef __XTENSA_CALL0_ABI__ - mov a2, sp /* a2 = pointer to exc frame */ - callx0 a4 /* call handler */ - #else - mov a6, sp /* a6 = pointer to exc frame */ - callx4 a4 /* call handler */ - #endif - -.L_xt_user_done: - - /* Restore context and return */ - call0 _xt_context_restore - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, PS - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_1 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove exception frame */ - rsync /* ensure PS and EPC written */ - rfe /* PS.EXCM is cleared */ - - -/* --------------------------------------------------------------------------------- - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. --------------------------------------------------------------------------------- -*/ - - .global _xt_user_exit - .type _xt_user_exit,@function - .align 4 -_xt_user_exit: - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, PS - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_1 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure PS and EPC written */ - rfe /* PS.EXCM is cleared */ - - -/* --------------------------------------------------------------------------------- -Syscall Exception Handler (jumped to from User Exception Handler). -Syscall 0 is required to spill the register windows (no-op in Call 0 ABI). -Only syscall 0 is handled here. Other syscalls return -1 to caller in a2. --------------------------------------------------------------------------------- -*/ - - .text - .type _xt_syscall_exc,@function - .align 4 -_xt_syscall_exc: - - #ifdef __XTENSA_CALL0_ABI__ - /* - Save minimal regs for scratch. Syscall 0 does nothing in Call0 ABI. - Use a minimal stack frame (16B) to save A2 & A3 for scratch. - PS.EXCM could be cleared here, but unlikely to improve worst-case latency. - rsr a0, PS - addi a0, a0, -PS_EXCM_MASK - wsr a0, PS - */ - addi sp, sp, -16 - s32i a2, sp, 8 - s32i a3, sp, 12 - #else /* Windowed ABI */ - /* - Save necessary context and spill the register windows. - PS.EXCM is still set and must remain set until after the spill. - Reuse context save function though it saves more than necessary. - For this reason, a full interrupt stack frame is allocated. - */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ - s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ - call0 _xt_context_save - #endif - - /* - Grab the interruptee's PC and skip over the 'syscall' instruction. - If it's at the end of a zero-overhead loop and it's not on the last - iteration, decrement loop counter and skip to beginning of loop. - */ - rsr a2, EPC_1 /* a2 = PC of 'syscall' */ - addi a3, a2, 3 /* ++PC */ - #if XCHAL_HAVE_LOOPS - rsr a0, LEND /* if (PC == LEND */ - bne a3, a0, 1f - rsr a0, LCOUNT /* && LCOUNT != 0) */ - beqz a0, 1f /* { */ - addi a0, a0, -1 /* --LCOUNT */ - rsr a3, LBEG /* PC = LBEG */ - wsr a0, LCOUNT /* } */ - #endif -1: wsr a3, EPC_1 /* update PC */ - - /* Restore interruptee's context and return from exception. */ - #ifdef __XTENSA_CALL0_ABI__ - l32i a2, sp, 8 - l32i a3, sp, 12 - addi sp, sp, 16 - #else - call0 _xt_context_restore - addi sp, sp, XT_STK_FRMSZ - #endif - movi a0, -1 - movnez a2, a0, a2 /* return -1 if not syscall 0 */ - rsr a0, EXCSAVE_1 - rfe - -/* --------------------------------------------------------------------------------- -Co-Processor Exception Handler (jumped to from User Exception Handler). -These exceptions are generated by co-processor instructions, which are only -allowed in thread code (not in interrupts or kernel code). This restriction is -deliberately imposed to reduce the burden of state-save/restore in interrupts. --------------------------------------------------------------------------------- -*/ -#if XCHAL_CP_NUM > 0 - - .section .rodata, "a" - -/* Offset to CP n save area in thread's CP save area. */ - .global _xt_coproc_sa_offset - .type _xt_coproc_sa_offset,@object - .align 16 /* minimize crossing cache boundaries */ -_xt_coproc_sa_offset: - .word XT_CP0_SA, XT_CP1_SA, XT_CP2_SA, XT_CP3_SA - .word XT_CP4_SA, XT_CP5_SA, XT_CP6_SA, XT_CP7_SA - -/* Bitmask for CP n's CPENABLE bit. */ - .type _xt_coproc_mask,@object - .align 16,,8 /* try to keep it all in one cache line */ - .set i, 0 -_xt_coproc_mask: - .rept XCHAL_CP_MAX - .long (i<<16) | (1<= 2 - - .begin literal_prefix .Level2InterruptVector - .section .Level2InterruptVector.text, "ax" - .global _Level2Vector - .type _Level2Vector,@function - .align 4 - .literal_position - -_Level2Vector: - wsr a0, EXCSAVE_2 /* preserve a0 */ - call0 _xt_medint2 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_medint2,@function - .align 4 -_xt_medint2: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_2 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_2 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_2 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint2_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(2) | PS_UM - #else - movi a0, PS_INTLEVEL(2) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 2 XCHAL_INTLEVEL2_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint2_exit - .type _xt_medint2_exit,@function - .align 4 -_xt_medint2_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_2 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_2 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 2 - -#endif /* Level 2 */ - -#if XCHAL_EXCM_LEVEL >= 3 - - .begin literal_prefix .Level3InterruptVector - .section .Level3InterruptVector.text, "ax" - .global _Level3Vector - .type _Level3Vector,@function - .align 4 - .literal_position - -_Level3Vector: - wsr a0, EXCSAVE_3 /* preserve a0 */ - call0 _xt_medint3 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_medint3,@function - .align 4 -_xt_medint3: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_3 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_3 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_3 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint3_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(3) | PS_UM - #else - movi a0, PS_INTLEVEL(3) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 3 XCHAL_INTLEVEL3_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint3_exit - .type _xt_medint3_exit,@function - .align 4 -_xt_medint3_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_3 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_3 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 3 - -#endif /* Level 3 */ - -#if XCHAL_EXCM_LEVEL >= 4 - - .begin literal_prefix .Level4InterruptVector - .section .Level4InterruptVector.text, "ax" - .global _Level4Vector - .type _Level4Vector,@function - .align 4 - .literal_position - -_Level4Vector: - wsr a0, EXCSAVE_4 /* preserve a0 */ - call0 _xt_medint4 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint4,@function - .align 4 -_xt_medint4: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_4 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_4 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_4 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint4_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(4) | PS_UM - #else - movi a0, PS_INTLEVEL(4) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 4 XCHAL_INTLEVEL4_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint4_exit - .type _xt_medint4_exit,@function - .align 4 -_xt_medint4_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_4 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_4 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 4 - -#endif /* Level 4 */ - -#if XCHAL_EXCM_LEVEL >= 5 - - .begin literal_prefix .Level5InterruptVector - .section .Level5InterruptVector.text, "ax" - .global _Level5Vector - .type _Level5Vector,@function - .align 4 - .literal_position - -_Level5Vector: - wsr a0, EXCSAVE_5 /* preserve a0 */ - call0 _xt_medint5 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint5,@function - .align 4 -_xt_medint5: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_5 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_5 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_5 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint5_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(5) | PS_UM - #else - movi a0, PS_INTLEVEL(5) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 5 XCHAL_INTLEVEL5_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint5_exit - .type _xt_medint5_exit,@function - .align 4 -_xt_medint5_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_5 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_5 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 5 - -#endif /* Level 5 */ - -#if XCHAL_EXCM_LEVEL >= 6 - - .begin literal_prefix .Level6InterruptVector - .section .Level6InterruptVector.text, "ax" - .global _Level6Vector - .type _Level6Vector,@function - .align 4 - .literal_position - -_Level6Vector: - wsr a0, EXCSAVE_6 /* preserve a0 */ - call0 _xt_medint6 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint6,@function - .align 4 -_xt_medint6: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_6 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_6 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_6 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint6_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(6) | PS_UM - #else - movi a0, PS_INTLEVEL(6) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 6 XCHAL_INTLEVEL6_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint6_exit - .type _xt_medint6_exit,@function - .align 4 -_xt_medint6_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_6 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_6 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 6 - -#endif /* Level 6 */ - - -/******************************************************************************* - -HIGH PRIORITY (LEVEL > XCHAL_EXCM_LEVEL) INTERRUPT VECTORS AND HANDLERS - -High priority interrupts are by definition those with priorities greater -than XCHAL_EXCM_LEVEL. This includes non-maskable (NMI). High priority -interrupts cannot interact with the RTOS, that is they must save all regs -they use and not call any RTOS function. - -A further restriction imposed by the Xtensa windowed architecture is that -high priority interrupts must not modify the stack area even logically -"above" the top of the interrupted stack (they need to provide their -own stack or static save area). - -Cadence Design Systems recommends high priority interrupt handlers be coded in assembly -and used for purposes requiring very short service times. - -Here are templates for high priority (level 2+) interrupt vectors. -They assume only one interrupt per level to avoid the burden of identifying -which interrupts at this level are pending and enabled. This allows for -minimum latency and avoids having to save/restore a2 in addition to a0. -If more than one interrupt per high priority level is configured, this burden -is on the handler which in any case must provide a way to save and restore -registers it uses without touching the interrupted stack. - -Each vector goes at a predetermined location according to the Xtensa -hardware configuration, which is ensured by its placement in a special -section known to the Xtensa linker support package (LSP). It performs -the minimum necessary before jumping to the handler in the .text section. - -*******************************************************************************/ - -/* -Currently only shells for high priority interrupt handlers are provided -here. However a template and example can be found in the Cadence Design Systems tools -documentation: "Microprocessor Programmer's Guide". -*/ - -#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2 - - .begin literal_prefix .Level2InterruptVector - .section .Level2InterruptVector.text, "ax" - .global _Level2Vector - .type _Level2Vector,@function - .align 4 -_Level2Vector: - wsr a0, EXCSAVE_2 /* preserve a0 */ - call0 _xt_highint2 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_highint2,@function - .align 4 -_xt_highint2: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 2<<2 - beqz a0, 1f -.Ln_xt_highint2_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 2 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint2_exit: - rsr a0, EXCSAVE_2 /* restore a0 */ - rfi 2 - -#endif /* Level 2 */ - -#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3 - - .begin literal_prefix .Level3InterruptVector - .section .Level3InterruptVector.text, "ax" - .global _Level3Vector - .type _Level3Vector,@function - .align 4 -_Level3Vector: - wsr a0, EXCSAVE_3 /* preserve a0 */ - call0 _xt_highint3 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint3,@function - .align 4 -_xt_highint3: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 3<<2 - beqz a0, 1f -.Ln_xt_highint3_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 3 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint3_exit: - rsr a0, EXCSAVE_3 /* restore a0 */ - rfi 3 - -#endif /* Level 3 */ - -#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4 - - .begin literal_prefix .Level4InterruptVector - .section .Level4InterruptVector.text, "ax" - .global _Level4Vector - .type _Level4Vector,@function - .align 4 -_Level4Vector: - wsr a0, EXCSAVE_4 /* preserve a0 */ - call0 _xt_highint4 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint4,@function - .align 4 -_xt_highint4: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 4<<2 - beqz a0, 1f -.Ln_xt_highint4_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 4 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint4_exit: - rsr a0, EXCSAVE_4 /* restore a0 */ - rfi 4 - -#endif /* Level 4 */ - -#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5 - - .begin literal_prefix .Level5InterruptVector - .section .Level5InterruptVector.text, "ax" - .global _Level5Vector - .type _Level5Vector,@function - .align 4 -_Level5Vector: - wsr a0, EXCSAVE_5 /* preserve a0 */ - call0 _xt_highint5 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint5,@function - .align 4 -_xt_highint5: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 5<<2 - beqz a0, 1f -.Ln_xt_highint5_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 5 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint5_exit: - rsr a0, EXCSAVE_5 /* restore a0 */ - rfi 5 - -#endif /* Level 5 */ - -#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6 - - .begin literal_prefix .Level6InterruptVector - .section .Level6InterruptVector.text, "ax" - .global _Level6Vector - .type _Level6Vector,@function - .align 4 -_Level6Vector: - wsr a0, EXCSAVE_6 /* preserve a0 */ - call0 _xt_highint6 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint6,@function - .align 4 -_xt_highint6: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 6<<2 - beqz a0, 1f -.Ln_xt_highint6_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 6 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint6_exit: - rsr a0, EXCSAVE_6 /* restore a0 */ - rfi 6 - -#endif /* Level 6 */ - -#if XCHAL_HAVE_NMI - - .begin literal_prefix .NMIExceptionVector - .section .NMIExceptionVector.text, "ax" - .global _NMIExceptionVector - .type _NMIExceptionVector,@function - .align 4 -_NMIExceptionVector: - wsr a0, EXCSAVE + XCHAL_NMILEVEL _ /* preserve a0 */ - call0 _xt_nmi /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_nmi,@function - .align 4 -_xt_nmi: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, XCHAL_NMILEVEL<<2 - beqz a0, 1f -.Ln_xt_nmi_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY NON-MASKABLE INTERRUPT (NMI) HANDLER CODE HERE. - */ - - .align 4 -.L_xt_nmi_exit: - rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */ - rfi XCHAL_NMILEVEL - -#endif /* NMI */ - - -/******************************************************************************* - -WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION HANDLER - -Here is the code for each window overflow/underflow exception vector and -(interspersed) efficient code for handling the alloca exception cause. -Window exceptions are handled entirely in the vector area and are very -tight for performance. The alloca exception is also handled entirely in -the window vector area so comes at essentially no cost in code size. -Users should never need to modify them and Cadence Design Systems recommends -they do not. - -Window handlers go at predetermined vector locations according to the -Xtensa hardware configuration, which is ensured by their placement in a -special section known to the Xtensa linker support package (LSP). Since -their offsets in that section are always the same, the LSPs do not define -a section per vector. - -These things are coded for XEA2 only (XEA1 is not supported). - -Note on Underflow Handlers: -The underflow handler for returning from call[i+1] to call[i] -must preserve all the registers from call[i+1]'s window. -In particular, a0 and a1 must be preserved because the RETW instruction -will be reexecuted (and may even underflow if an intervening exception -has flushed call[i]'s registers). -Registers a2 and up may contain return values. - -*******************************************************************************/ - -#if XCHAL_HAVE_WINDOWED - - .section .WindowVectors.text, "ax" - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call4. - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call4 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a3 are registers to be saved; - a4-a15 must be preserved; - a5 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x0 - .global _WindowOverflow4 -_WindowOverflow4: - - s32e a0, a5, -16 /* save a0 to call[j+1]'s stack frame */ - s32e a1, a5, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a5, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a5, -4 /* save a3 to call[j+1]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call4 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call4 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a3 are undefined, must be reloaded with call[i].reg[0..3]; - a4-a15 must be preserved (they are call[i+1].reg[0..11]); - a5 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x40 - .global _WindowUnderflow4 -_WindowUnderflow4: - - l32e a0, a5, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a5, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a5, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a3, a5, -4 /* restore a3 from call[i+1]'s stack frame */ - rfwu - -/* --------------------------------------------------------------------------------- -Handle alloca exception generated by interruptee executing 'movsp'. -This uses space between the window vectors, so is essentially "free". -All interruptee's regs are intact except a0 which is saved in EXCSAVE_1, -and PS.EXCM has been set by the exception hardware (can't be interrupted). -The fact the alloca exception was taken means the registers associated with -the base-save area have been spilled and will be restored by the underflow -handler, so those 4 registers are available for scratch. -The code is optimized to avoid unaligned branches and minimize cache misses. --------------------------------------------------------------------------------- -*/ - - .align 4 - .global _xt_alloca_exc -_xt_alloca_exc: - - rsr a0, WINDOWBASE /* grab WINDOWBASE before rotw changes it */ - rotw -1 /* WINDOWBASE goes to a4, new a0-a3 are scratch */ - rsr a2, PS - extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS - xor a3, a3, a4 /* bits changed from old to current windowbase */ - rsr a4, EXCSAVE_1 /* restore original a0 (now in a4) */ - slli a3, a3, XCHAL_PS_OWB_SHIFT - xor a2, a2, a3 /* flip changed bits in old window base */ - wsr a2, PS /* update PS.OWB to new window base */ - rsync - - _bbci.l a4, 31, _WindowUnderflow4 - rotw -1 /* original a0 goes to a8 */ - _bbci.l a8, 30, _WindowUnderflow8 - rotw -1 - j _WindowUnderflow12 - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call8 - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call8 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a7 are registers to be saved; - a8-a15 must be preserved; - a9 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x80 - .global _WindowOverflow8 -_WindowOverflow8: - - s32e a0, a9, -16 /* save a0 to call[j+1]'s stack frame */ - l32e a0, a1, -12 /* a0 <- call[j-1]'s sp - (used to find end of call[j]'s frame) */ - s32e a1, a9, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a9, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a9, -4 /* save a3 to call[j+1]'s stack frame */ - s32e a4, a0, -32 /* save a4 to call[j]'s stack frame */ - s32e a5, a0, -28 /* save a5 to call[j]'s stack frame */ - s32e a6, a0, -24 /* save a6 to call[j]'s stack frame */ - s32e a7, a0, -20 /* save a7 to call[j]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call8 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call8 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a7 are undefined, must be reloaded with call[i].reg[0..7]; - a8-a15 must be preserved (they are call[i+1].reg[0..7]); - a9 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0xC0 - .global _WindowUnderflow8 -_WindowUnderflow8: - - l32e a0, a9, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a9, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a9, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a7, a1, -12 /* a7 <- call[i-1]'s sp - (used to find end of call[i]'s frame) */ - l32e a3, a9, -4 /* restore a3 from call[i+1]'s stack frame */ - l32e a4, a7, -32 /* restore a4 from call[i]'s stack frame */ - l32e a5, a7, -28 /* restore a5 from call[i]'s stack frame */ - l32e a6, a7, -24 /* restore a6 from call[i]'s stack frame */ - l32e a7, a7, -20 /* restore a7 from call[i]'s stack frame */ - rfwu - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call12 - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call12 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a11 are registers to be saved; - a12-a15 must be preserved; - a13 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x100 - .global _WindowOverflow12 -_WindowOverflow12: - - s32e a0, a13, -16 /* save a0 to call[j+1]'s stack frame */ - l32e a0, a1, -12 /* a0 <- call[j-1]'s sp - (used to find end of call[j]'s frame) */ - s32e a1, a13, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a13, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a13, -4 /* save a3 to call[j+1]'s stack frame */ - s32e a4, a0, -48 /* save a4 to end of call[j]'s stack frame */ - s32e a5, a0, -44 /* save a5 to end of call[j]'s stack frame */ - s32e a6, a0, -40 /* save a6 to end of call[j]'s stack frame */ - s32e a7, a0, -36 /* save a7 to end of call[j]'s stack frame */ - s32e a8, a0, -32 /* save a8 to end of call[j]'s stack frame */ - s32e a9, a0, -28 /* save a9 to end of call[j]'s stack frame */ - s32e a10, a0, -24 /* save a10 to end of call[j]'s stack frame */ - s32e a11, a0, -20 /* save a11 to end of call[j]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call12 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call12 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a11 are undefined, must be reloaded with call[i].reg[0..11]; - a12-a15 must be preserved (they are call[i+1].reg[0..3]); - a13 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x140 - .global _WindowUnderflow12 -_WindowUnderflow12: - - l32e a0, a13, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a13, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a13, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a11, a1, -12 /* a11 <- call[i-1]'s sp - (used to find end of call[i]'s frame) */ - l32e a3, a13, -4 /* restore a3 from call[i+1]'s stack frame */ - l32e a4, a11, -48 /* restore a4 from end of call[i]'s stack frame */ - l32e a5, a11, -44 /* restore a5 from end of call[i]'s stack frame */ - l32e a6, a11, -40 /* restore a6 from end of call[i]'s stack frame */ - l32e a7, a11, -36 /* restore a7 from end of call[i]'s stack frame */ - l32e a8, a11, -32 /* restore a8 from end of call[i]'s stack frame */ - l32e a9, a11, -28 /* restore a9 from end of call[i]'s stack frame */ - l32e a10, a11, -24 /* restore a10 from end of call[i]'s stack frame */ - l32e a11, a11, -20 /* restore a11 from end of call[i]'s stack frame */ - rfwu - -#endif /* XCHAL_HAVE_WINDOWED */ diff --git a/portable/ThirdParty/xClang/XCOREAI/port.c b/portable/ThirdParty/xClang/XCOREAI/port.c index ba4598b6b..ac12aa31a 100644 --- a/portable/ThirdParty/xClang/XCOREAI/port.c +++ b/portable/ThirdParty/xClang/XCOREAI/port.c @@ -12,6 +12,15 @@ static hwtimer_t xKernelTimer; uint32_t ulPortYieldRequired[ portMAX_CORE_COUNT ] = { pdFALSE }; +/* When this port was designed, it was assumed that pxCurrentTCBs would always + exist and that it would always be an array containing pointers to the current + TCBs for each core. In v11, this is not the case; if we are only running one + core, the symbol is pxCurrentTCB instead. Therefore, this port adds a layer + of indirection - we populate this pointer-to-pointer in the RTOS kernel entry + function below. This makes this port agnostic to whether it is running on SMP + or singlecore RTOS. */ +void ** xcorePvtTCBContainer; + /*-----------------------------------------------------------*/ void vIntercoreInterruptISR( void ) @@ -140,6 +149,28 @@ DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void ) } #endif + /* Populate the TCBContainer depending on whether we're singlecore or SMP */ + #if ( configNUMBER_OF_CORES == 1 ) + { + asm volatile ( + "ldaw %0, dp[pxCurrentTCB]\n\t" + : "=r"(xcorePvtTCBContainer) + : /* no inputs */ + : /* no clobbers */ + ); + } + #else + { + asm volatile ( + "ldaw %0, dp[pxCurrentTCBs]\n\t" + : "=r"(xcorePvtTCBContainer) + : /* no inputs */ + : /* no clobbers */ + ); + } + + #endif + debug_printf( "FreeRTOS Core %d initialized\n", xCoreID ); /* @@ -147,8 +178,8 @@ DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void ) * to run and jump into it. */ asm volatile ( - "mov r6, %0\n\t" /* R6 must be the FreeRTOS core ID*/ - "ldaw r5, dp[pxCurrentTCBs]\n\t" /* R5 must be the TCB list which is indexed by R6 */ + "mov r6, %0\n\t" /* R6 must be the FreeRTOS core ID. In singlecore this is always 0. */ + "ldw r5, dp[xcorePvtTCBContainer]\n\t" /* R5 must be the TCB list which is indexed by R6 */ "bu _freertos_restore_ctx\n\t" : /* no outputs */ : "r" ( xCoreID ) diff --git a/portable/ThirdParty/xClang/XCOREAI/portasm.S b/portable/ThirdParty/xClang/XCOREAI/portasm.S index 7445672a0..64b7b9d9a 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portasm.S +++ b/portable/ThirdParty/xClang/XCOREAI/portasm.S @@ -14,11 +14,8 @@ rest of the ISR callback functions. */ .issue_mode dual .cc_top kexcept.function, kexcept kexcept: - ldc r11, 0x0008 - shl r11, r11, 16 - ldc r9, 0x0080 - or r11, r11, r9 - bau r11 //_TrapHandler is at 0x00080080. TODO: Is it always? Why can't I access the symbol _TrapHandler? + bu _DoException /* This symbol is generated by the toolchain and */ + /* provides graceful exception handling */ _yield: {set sp, r4 /* Restore the task's SP to save the rest of its context. */ @@ -123,7 +120,7 @@ _yield_continue: ldaw r11, sp[37]} vstc r11[0] #endif - ldaw r5, dp[pxCurrentTCBs] /* Get the current TCB array into r5. */ + ldw r5, dp[xcorePvtTCBContainer] ldw r1, r5[r0] /* Get this core's current TCB pointer into r1. */ stw r4, r1[0x0] /* Save the current task's SP to the first */ /* word (top of stack) in the current TCB. */ diff --git a/portable/ThirdParty/xClang/XCOREAI/portmacro.h b/portable/ThirdParty/xClang/XCOREAI/portmacro.h index 06f2b75dc..088133314 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portmacro.h +++ b/portable/ThirdParty/xClang/XCOREAI/portmacro.h @@ -139,9 +139,6 @@ #define portSET_INTERRUPT_MASK() rtos_interrupt_mask_all() #define portCLEAR_INTERRUPT_MASK( ulState ) rtos_interrupt_mask_set( ulState ) - #define portSET_INTERRUPT_MASK_FROM_ISR() ( 0 ) - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( ( void ) x ) - /* * Will enable interrupts if ulState is non-zero. */ @@ -155,10 +152,11 @@ #define portASSERT_IF_IN_ISR() configASSERT( portCHECK_IF_IN_ISR() == 0 ) - #define portGET_ISR_LOCK() rtos_lock_acquire( 0 ) - #define portRELEASE_ISR_LOCK() rtos_lock_release( 0 ) - #define portGET_TASK_LOCK() rtos_lock_acquire( 1 ) - #define portRELEASE_TASK_LOCK() rtos_lock_release( 1 ) + #define portGET_ISR_LOCK( xCoreID ) do{ ( void )( xCoreID ); rtos_lock_acquire( 0 ); } while( 0 ) + #define portRELEASE_ISR_LOCK( xCoreID ) do{ ( void )( xCoreID ); rtos_lock_release( 0 ); } while( 0 ) + #define portGET_TASK_LOCK( xCoreID ) do{ ( void )( xCoreID ); rtos_lock_acquire( 1 ); } while( 0 ) + #define portRELEASE_TASK_LOCK( xCoreID ) do{ ( void )( xCoreID ); rtos_lock_release( 1 ); } while( 0 ) + void vTaskEnterCritical( void ); void vTaskExitCritical( void ); diff --git a/portable/WizC/PIC18/Drivers/Tick/Tick.c b/portable/WizC/PIC18/Drivers/Tick/Tick.c index 5dfa080b6..53c2dbcc7 100644 --- a/portable/WizC/PIC18/Drivers/Tick/Tick.c +++ b/portable/WizC/PIC18/Drivers/Tick/Tick.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/WizC/PIC18/Drivers/Tick/isrTick.c b/portable/WizC/PIC18/Drivers/Tick/isrTick.c index f61047dc1..d68f8431f 100644 --- a/portable/WizC/PIC18/Drivers/Tick/isrTick.c +++ b/portable/WizC/PIC18/Drivers/Tick/isrTick.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/WizC/PIC18/addFreeRTOS.h b/portable/WizC/PIC18/addFreeRTOS.h index 178ca1089..386ae9f7e 100644 --- a/portable/WizC/PIC18/addFreeRTOS.h +++ b/portable/WizC/PIC18/addFreeRTOS.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/WizC/PIC18/port.c b/portable/WizC/PIC18/port.c index edabae61d..6941ece4f 100644 --- a/portable/WizC/PIC18/port.c +++ b/portable/WizC/PIC18/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/WizC/PIC18/portmacro.h b/portable/WizC/PIC18/portmacro.h index 44d26592f..abeb955d0 100644 --- a/portable/WizC/PIC18/portmacro.h +++ b/portable/WizC/PIC18/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -154,7 +154,7 @@ extern uint8_t ucCriticalNesting; /* * The minimal stacksize is calculated on the first reference of * portMINIMAL_STACK_SIZE. Some input to this calculation is - * compiletime determined, other input is port-defined (see port.c) + * compile time determined, other input is port-defined (see port.c) */ extern uint16_t usPortCALCULATE_MINIMAL_STACK_SIZE( void ); extern uint16_t usCalcMinStackSize; diff --git a/portable/oWatcom/16BitDOS/Flsh186/port.c b/portable/oWatcom/16BitDOS/Flsh186/port.c index cc8863d1d..4b900b6a8 100644 --- a/portable/oWatcom/16BitDOS/Flsh186/port.c +++ b/portable/oWatcom/16BitDOS/Flsh186/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/oWatcom/16BitDOS/Flsh186/portmacro.h b/portable/oWatcom/16BitDOS/Flsh186/portmacro.h index 952e3f680..efa43611b 100644 --- a/portable/oWatcom/16BitDOS/Flsh186/portmacro.h +++ b/portable/oWatcom/16BitDOS/Flsh186/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/oWatcom/16BitDOS/PC/port.c b/portable/oWatcom/16BitDOS/PC/port.c index 6cb2de9e8..bbee5ec68 100644 --- a/portable/oWatcom/16BitDOS/PC/port.c +++ b/portable/oWatcom/16BitDOS/PC/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/oWatcom/16BitDOS/PC/portmacro.h b/portable/oWatcom/16BitDOS/PC/portmacro.h index 2fb753411..99b29dbc7 100644 --- a/portable/oWatcom/16BitDOS/PC/portmacro.h +++ b/portable/oWatcom/16BitDOS/PC/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/oWatcom/16BitDOS/common/portasm.h b/portable/oWatcom/16BitDOS/common/portasm.h index f77e2b553..b9cb0e697 100644 --- a/portable/oWatcom/16BitDOS/common/portasm.h +++ b/portable/oWatcom/16BitDOS/common/portasm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -63,7 +63,7 @@ debugger). The true stack pointer is then stored in the bp register. We add "les bx, dword ptr pxCurrentTCB" \ "mov ss, es:[ bx + 2 ]" \ "mov sp, es:[ bx ]" \ - "mov bp, sp" /* Prepair the bp register for the restoration of the SP in the compiler generated portion of the ISR */ \ + "mov bp, sp" /* Prepare the bp register for the restoration of the SP in the compiler generated portion of the ISR */ \ "add bp, 0x0002" diff --git a/portable/oWatcom/16BitDOS/common/portcomn.c b/portable/oWatcom/16BitDOS/common/portcomn.c index 2a7b66637..d05b1fd1f 100644 --- a/portable/oWatcom/16BitDOS/common/portcomn.c +++ b/portable/oWatcom/16BitDOS/common/portcomn.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/template/port.c b/portable/template/port.c index d4eb56eac..7cac1c991 100644 --- a/portable/template/port.c +++ b/portable/template/port.c @@ -19,6 +19,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { + ( void ) pxTopOfStack; + ( void ) pvParameters; + ( void ) * pxCode; + return NULL; } diff --git a/portable/template/portmacro.h b/portable/template/portmacro.h index 199053208..a426f0003 100644 --- a/portable/template/portmacro.h +++ b/portable/template/portmacro.h @@ -34,13 +34,13 @@ typedef unsigned char UBaseType_t; #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff + #define portMAX_DELAY ( TickType_t ) 0xffffU #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + #define portMAX_DELAY ( TickType_t ) 0xffffffffU #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) typedef uint64_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffULL + #define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffU #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif @@ -105,7 +105,7 @@ extern void vPortYield( void ); #define portYIELD() vPortYield() /* Task function macros as described on the FreeRTOS.org WEB site. */ -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) __attribute__( ( noreturn ) ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #if ( configNUMBER_OF_CORES > 1 ) @@ -123,19 +123,19 @@ extern void vPortYield( void ); /* Acquire the TASK lock. TASK lock is a recursive lock. * It should be able to be locked by the same core multiple times. */ - #define portGET_TASK_LOCK() do {} while( 0 ) + #define portGET_TASK_LOCK( xCoreID ) do {} while( 0 ) /* Release the TASK lock. If a TASK lock is locked by the same core multiple times, * it should be released as many times as it is locked. */ - #define portRELEASE_TASK_LOCK() do {} while( 0 ) + #define portRELEASE_TASK_LOCK( xCoreID ) do {} while( 0 ) /* Acquire the ISR lock. ISR lock is a recursive lock. * It should be able to be locked by the same core multiple times. */ - #define portGET_ISR_LOCK() do {} while( 0 ) + #define portGET_ISR_LOCK( xCoreID ) do {} while( 0 ) /* Release the ISR lock. If a ISR lock is locked by the same core multiple times, \ * it should be released as many times as it is locked. */ - #define portRELEASE_ISR_LOCK() do {} while( 0 ) + #define portRELEASE_ISR_LOCK( xCoreID ) do {} while( 0 ) #endif /* if ( configNUMBER_OF_CORES > 1 ) */ diff --git a/queue.c b/queue.c index 18618202c..a967839de 100644 --- a/queue.c +++ b/queue.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -247,7 +247,7 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, * other tasks that are waiting for the same mutex. This function returns * that priority. */ - static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + static UBaseType_t prvGetHighestPriorityOfWaitToReceiveList( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; #endif /*-----------------------------------------------------------*/ @@ -418,7 +418,7 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue, #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) { - /* Queues can be allocated wither statically or dynamically, so + /* Queues can be allocated either statically or dynamically, so * note this queue was allocated statically in case the queue is * later deleted. */ pxNewQueue->ucStaticallyAllocated = pdTRUE; @@ -513,7 +513,10 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue, /* Check for multiplication overflow. */ ( ( SIZE_MAX / uxQueueLength ) >= uxItemSize ) && /* Check for addition overflow. */ - ( ( UBaseType_t ) ( SIZE_MAX - sizeof( Queue_t ) ) >= ( uxQueueLength * uxItemSize ) ) ) + /* MISRA Ref 14.3.1 [Configuration dependent invariant] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-143. */ + /* coverity[misra_c_2012_rule_14_3_violation] */ + ( ( SIZE_MAX - sizeof( Queue_t ) ) >= ( size_t ) ( ( size_t ) uxQueueLength * ( size_t ) uxItemSize ) ) ) { /* Allocate enough space to hold the maximum number of items that * can be in the queue at any time. It is valid for uxItemSize to be @@ -830,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 @@ -842,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 { @@ -1165,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 @@ -1190,7 +1199,10 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, * read, instead return a flag to say whether a context switch is required or * not (i.e. has a task with a higher priority than us been woken by this * post). */ - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) { @@ -1338,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 @@ -1365,7 +1375,10 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; @@ -1838,13 +1851,13 @@ BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, * has timed out the priority should be disinherited * again, but only as low as the next highest priority * task that is waiting for the same mutex. */ - uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue ); + uxHighestWaitingPriority = prvGetHighestPriorityOfWaitToReceiveList( pxQueue ); /* vTaskPriorityDisinheritAfterTimeout uses the uxHighestWaitingPriority * parameter to index pxReadyTasksLists when adding the task holding * mutex to the ready list for its new priority. Coverity thinks that * it can result in out-of-bounds access which is not true because - * uxHighestWaitingPriority, as returned by prvGetDisinheritPriorityAfterTimeout, + * uxHighestWaitingPriority, as returned by prvGetHighestPriorityOfWaitToReceiveList, * is capped at ( configMAX_PRIORITIES - 1 ). */ /* coverity[overrun] */ vTaskPriorityDisinheritAfterTimeout( pxQueue->u.xSemaphore.xMutexHolder, uxHighestWaitingPriority ); @@ -1879,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 ) ) @@ -2055,7 +2065,10 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; @@ -2133,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 @@ -2153,7 +2165,10 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { /* Cannot block in an ISR, so check there is data available. */ if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) @@ -2190,11 +2205,11 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) configASSERT( xQueue ); - taskENTER_CRITICAL(); + portBASE_TYPE_ENTER_CRITICAL(); { uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; } - taskEXIT_CRITICAL(); + portBASE_TYPE_EXIT_CRITICAL(); traceRETURN_uxQueueMessagesWaiting( uxReturn ); @@ -2211,11 +2226,11 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) configASSERT( pxQueue ); - taskENTER_CRITICAL(); + portBASE_TYPE_ENTER_CRITICAL(); { uxReturn = ( UBaseType_t ) ( pxQueue->uxLength - pxQueue->uxMessagesWaiting ); } - taskEXIT_CRITICAL(); + portBASE_TYPE_EXIT_CRITICAL(); traceRETURN_uxQueueSpacesAvailable( uxReturn ); @@ -2350,7 +2365,7 @@ UBaseType_t uxQueueGetQueueLength( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION #if ( configUSE_MUTEXES == 1 ) - static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) + static UBaseType_t prvGetHighestPriorityOfWaitToReceiveList( const Queue_t * const pxQueue ) { UBaseType_t uxHighestPriorityOfWaitingTasks; @@ -3174,7 +3189,27 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) return pxQueue; } -#endif /* configUSE_QUEUE_SETS */ +#endif /* #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t xQueueCreateSetStatic( const UBaseType_t uxEventQueueLength, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue ) + { + QueueSetHandle_t pxQueue; + + traceENTER_xQueueCreateSetStatic( uxEventQueueLength ); + + pxQueue = xQueueGenericCreateStatic( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), pucQueueStorage, pxStaticQueue, queueQUEUE_TYPE_SET ); + + traceRETURN_xQueueCreateSetStatic( pxQueue ); + + return pxQueue; + } + +#endif /* #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_QUEUE_SETS == 1 ) diff --git a/stream_buffer.c b/stream_buffer.c index 3ea7baa4b..4f13c679b 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -39,45 +39,52 @@ #include "task.h" #include "stream_buffer.h" -#if ( configUSE_TASK_NOTIFICATIONS != 1 ) - #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c -#endif - -#if ( INCLUDE_xTaskGetCurrentTaskHandle != 1 ) - #error INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 to build stream_buffer.c -#endif - /* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/* This entire source file will be skipped if the application is not configured + * to include stream buffer functionality. This #if is closed at the very bottom + * of this file. If you want to include stream buffers then ensure + * configUSE_STREAM_BUFFERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_STREAM_BUFFERS == 1 ) + + #if ( configUSE_TASK_NOTIFICATIONS != 1 ) + #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c + #endif + + #if ( INCLUDE_xTaskGetCurrentTaskHandle != 1 ) + #error INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 to build stream_buffer.c + #endif + /* If the user has not provided application specific Rx notification macros, * or #defined the notification macros away, then provide default implementations * that uses task notifications. */ -#ifndef sbRECEIVE_COMPLETED - #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ - do \ - { \ - vTaskSuspendAll(); \ - { \ - if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ - { \ - ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \ - ( uint32_t ) 0, \ - eNoAction ); \ - ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ - } \ - } \ - ( void ) xTaskResumeAll(); \ + #ifndef sbRECEIVE_COMPLETED + #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ + do \ + { \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotifyIndexed( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( pxStreamBuffer )->uxNotificationIndex, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); \ } while( 0 ) -#endif /* sbRECEIVE_COMPLETED */ + #endif /* sbRECEIVE_COMPLETED */ /* If user has provided a per-instance receive complete callback, then * invoke the callback else use the receive complete macro which is provided by default for all instances. */ -#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) - #define prvRECEIVE_COMPLETED( pxStreamBuffer ) \ + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvRECEIVE_COMPLETED( pxStreamBuffer ) \ do { \ if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ { \ @@ -88,34 +95,35 @@ sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ); \ } \ } while( 0 ) -#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ - #define prvRECEIVE_COMPLETED( pxStreamBuffer ) sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ) -#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvRECEIVE_COMPLETED( pxStreamBuffer ) sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ) + #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ -#ifndef sbRECEIVE_COMPLETED_FROM_ISR - #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ - pxHigherPriorityTaskWoken ) \ - do { \ - UBaseType_t uxSavedInterruptStatus; \ - \ - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ - { \ - if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ - { \ - ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \ - ( uint32_t ) 0, \ - eNoAction, \ - ( pxHigherPriorityTaskWoken ) ); \ - ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ - } \ - } \ - taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ + #ifndef sbRECEIVE_COMPLETED_FROM_ISR + #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ + pxHigherPriorityTaskWoken ) \ + do { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( pxStreamBuffer )->uxNotificationIndex, \ + ( uint32_t ) 0, \ + eNoAction, \ + ( pxHigherPriorityTaskWoken ) ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ } while( 0 ) -#endif /* sbRECEIVE_COMPLETED_FROM_ISR */ + #endif /* sbRECEIVE_COMPLETED_FROM_ISR */ -#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) - #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ - pxHigherPriorityTaskWoken ) \ + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ + pxHigherPriorityTaskWoken ) \ do { \ if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ { \ @@ -126,35 +134,36 @@ sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ } \ } while( 0 ) -#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ - #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) -#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ /* If the user has not provided an application specific Tx notification macro, * or #defined the notification macro away, then provide a default * implementation that uses task notifications. */ -#ifndef sbSEND_COMPLETED - #define sbSEND_COMPLETED( pxStreamBuffer ) \ - vTaskSuspendAll(); \ - { \ - if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ - { \ - ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \ - ( uint32_t ) 0, \ - eNoAction ); \ - ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ - } \ - } \ + #ifndef sbSEND_COMPLETED + #define sbSEND_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotifyIndexed( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( pxStreamBuffer )->uxNotificationIndex, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ ( void ) xTaskResumeAll() -#endif /* sbSEND_COMPLETED */ + #endif /* sbSEND_COMPLETED */ /* If user has provided a per-instance send completed callback, then * invoke the callback else use the send complete macro which is provided by default for all instances. */ -#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) - #define prvSEND_COMPLETED( pxStreamBuffer ) \ + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvSEND_COMPLETED( pxStreamBuffer ) \ do { \ if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ { \ @@ -165,34 +174,35 @@ sbSEND_COMPLETED( ( pxStreamBuffer ) ); \ } \ } while( 0 ) -#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ - #define prvSEND_COMPLETED( pxStreamBuffer ) sbSEND_COMPLETED( ( pxStreamBuffer ) ) -#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvSEND_COMPLETED( pxStreamBuffer ) sbSEND_COMPLETED( ( pxStreamBuffer ) ) + #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ -#ifndef sbSEND_COMPLETE_FROM_ISR - #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ - do { \ - UBaseType_t uxSavedInterruptStatus; \ - \ - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ - { \ - if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ - { \ - ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \ - ( uint32_t ) 0, \ - eNoAction, \ - ( pxHigherPriorityTaskWoken ) ); \ - ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ - } \ - } \ - taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ + #ifndef sbSEND_COMPLETE_FROM_ISR + #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + do { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( pxStreamBuffer )->uxNotificationIndex, \ + ( uint32_t ) 0, \ + eNoAction, \ + ( pxHigherPriorityTaskWoken ) ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ } while( 0 ) -#endif /* sbSEND_COMPLETE_FROM_ISR */ + #endif /* sbSEND_COMPLETE_FROM_ISR */ -#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) - #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ do { \ if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ { \ @@ -203,17 +213,18 @@ sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ } \ } while( 0 ) -#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ - #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) -#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ /* The number of bytes used to hold the length of a message in the buffer. */ -#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) + #define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) /* Bits stored in the ucFlags field of the stream buffer. */ -#define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ -#define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ + #define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ + #define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ + #define sbFLAGS_IS_BATCHING_BUFFER ( ( uint8_t ) 4 ) /* Set if the stream buffer was created as a batching buffer, meaning the receiver task will only unblock when the trigger level exceededs. */ /*-----------------------------------------------------------*/ @@ -237,6 +248,7 @@ typedef struct StreamBufferDef_t StreamBufferCallbackFunction_t pxSendCompletedCallback; /* Optional callback called on send complete. sbSEND_COMPLETED is called if this is NULL. */ StreamBufferCallbackFunction_t pxReceiveCompletedCallback; /* Optional callback called on receive complete. sbRECEIVE_COMPLETED is called if this is NULL. */ #endif + UBaseType_t uxNotificationIndex; /* The index we are using for notification, by default tskDEFAULT_INDEX_TO_NOTIFY. */ } StreamBuffer_t; /* @@ -315,28 +327,34 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ -#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, StreamBufferCallbackFunction_t pxSendCompletedCallback, StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) { void * pvAllocatedMemory; uint8_t ucFlags; - traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); + traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pxSendCompletedCallback, pxReceiveCompletedCallback ); /* In case the stream buffer is going to be used as a message buffer * (that is, it will hold discrete messages with a little meta data that * says how big the next message is) check the buffer will be large enough * to hold at least one message. */ - if( xIsMessageBuffer == pdTRUE ) + if( xStreamBufferType == sbTYPE_MESSAGE_BUFFER ) { /* Is a message buffer but not statically allocated. */ ucFlags = sbFLAGS_IS_MESSAGE_BUFFER; configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); } + else if( xStreamBufferType == sbTYPE_STREAM_BATCHING_BUFFER ) + { + /* Is a batching buffer but not statically allocated. */ + ucFlags = sbFLAGS_IS_BATCHING_BUFFER; + configASSERT( xBufferSizeBytes > 0 ); + } else { /* Not a message buffer and not statically allocated. */ @@ -387,11 +405,11 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); - traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pvAllocatedMemory ), xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pvAllocatedMemory ), xStreamBufferType ); } else { - traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType ); } traceRETURN_xStreamBufferGenericCreate( pvAllocatedMemory ); @@ -401,14 +419,14 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, /* coverity[misra_c_2012_rule_11_5_violation] */ return ( StreamBufferHandle_t ) pvAllocatedMemory; } -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, + BaseType_t xStreamBufferType, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, @@ -421,7 +439,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, StreamBufferHandle_t xReturn; uint8_t ucFlags; - traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); + traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ); configASSERT( pucStreamBufferStorageArea ); configASSERT( pxStaticStreamBuffer ); @@ -439,12 +457,18 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, * says how big the next message is) check the buffer will be large enough * to hold at least one message. */ - if( xIsMessageBuffer != pdFALSE ) + if( xStreamBufferType == sbTYPE_MESSAGE_BUFFER ) { /* Statically allocated message buffer. */ ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); } + else if( xStreamBufferType == sbTYPE_STREAM_BATCHING_BUFFER ) + { + /* Statically allocated batching buffer. */ + ucFlags = sbFLAGS_IS_BATCHING_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; + configASSERT( xBufferSizeBytes > 0 ); + } else { /* Statically allocated stream buffer. */ @@ -475,7 +499,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, * again. */ pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED; - traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xStreamBufferType ); /* MISRA Ref 11.3.1 [Misaligned access] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */ @@ -485,17 +509,17 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, else { xReturn = NULL; - traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType ); } traceRETURN_xStreamBufferGenericCreateStatic( xReturn ); return xReturn; } -#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + #endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ /*-----------------------------------------------------------*/ -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer, uint8_t ** ppucStreamBufferStorageArea, StaticStreamBuffer_t ** ppxStaticStreamBuffer ) @@ -527,7 +551,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, return xReturn; } -#endif /* configSUPPORT_STATIC_ALLOCATION */ + #endif /* configSUPPORT_STATIC_ALLOCATION */ /*-----------------------------------------------------------*/ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) @@ -628,6 +652,71 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) } /*-----------------------------------------------------------*/ +BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + BaseType_t xReturn = pdFAIL; + StreamBufferCallbackFunction_t pxSendCallback = NULL, pxReceiveCallback = NULL; + UBaseType_t uxSavedInterruptStatus; + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; + #endif + + traceENTER_xStreamBufferResetFromISR( xStreamBuffer ); + + configASSERT( pxStreamBuffer ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Store the stream buffer number so it can be restored after the + * reset. */ + uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber; + } + #endif + + /* Can only reset a message buffer if there are no tasks blocked on it. */ + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + { + if( ( pxStreamBuffer->xTaskWaitingToReceive == NULL ) && ( pxStreamBuffer->xTaskWaitingToSend == NULL ) ) + { + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + { + pxSendCallback = pxStreamBuffer->pxSendCompletedCallback; + pxReceiveCallback = pxStreamBuffer->pxReceiveCompletedCallback; + } + #endif + + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pxStreamBuffer->pucBuffer, + pxStreamBuffer->xLength, + pxStreamBuffer->xTriggerLevelBytes, + pxStreamBuffer->ucFlags, + pxSendCallback, + pxReceiveCallback ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + #endif + + traceSTREAM_BUFFER_RESET_FROM_ISR( xStreamBuffer ); + + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); + + traceRETURN_xStreamBufferResetFromISR( xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) { @@ -790,7 +879,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, if( xSpace < xRequiredSpace ) { /* Clear notification state as going to wait for space. */ - ( void ) xTaskNotifyStateClear( NULL ); + ( void ) xTaskNotifyStateClearIndexed( NULL, pxStreamBuffer->uxNotificationIndex ); /* Should only be one writer. */ configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL ); @@ -805,7 +894,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, taskEXIT_CRITICAL(); traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ); - ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + ( void ) xTaskNotifyWaitIndexed( pxStreamBuffer->uxNotificationIndex, ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); pxStreamBuffer->xTaskWaitingToSend = NULL; } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ); } @@ -886,6 +975,9 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, /* Was a task waiting for the data? */ if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) { + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); } else @@ -980,6 +1072,12 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, { xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; } + else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_BATCHING_BUFFER ) != ( uint8_t ) 0 ) + { + /* Force task to block if the batching buffer contains less bytes than + * the trigger level. */ + xBytesToStoreMessageLength = pxStreamBuffer->xTriggerLevelBytes; + } else { xBytesToStoreMessageLength = 0; @@ -997,11 +1095,13 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * xBytesToStoreMessageLength holds the number of bytes used to hold * the length of the next discrete message. If this function was * invoked by a stream buffer read then xBytesToStoreMessageLength will - * be 0. */ + * be 0. If this function was invoked by a stream batch buffer read + * then xBytesToStoreMessageLength will be xTriggerLevelBytes value + * for the buffer.*/ if( xBytesAvailable <= xBytesToStoreMessageLength ) { /* Clear notification state as going to wait for data. */ - ( void ) xTaskNotifyStateClear( NULL ); + ( void ) xTaskNotifyStateClearIndexed( NULL, pxStreamBuffer->uxNotificationIndex ); /* Should only be one reader. */ configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL ); @@ -1018,7 +1118,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, { /* Wait for data to be available. */ traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ); - ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + ( void ) xTaskNotifyWaitIndexed( pxStreamBuffer->uxNotificationIndex, ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); pxStreamBuffer->xTaskWaitingToReceive = NULL; /* Recheck the data available after blocking. */ @@ -1151,6 +1251,9 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, /* Was a task waiting for space in the buffer? */ if( xReceivedLength != ( size_t ) 0 ) { + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); } else @@ -1303,14 +1406,18 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer configASSERT( pxStreamBuffer ); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) { - ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, - ( uint32_t ) 0, - eNoAction, - pxHigherPriorityTaskWoken ); + ( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, + ( pxStreamBuffer )->uxNotificationIndex, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; xReturn = pdTRUE; } @@ -1338,14 +1445,18 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf configASSERT( pxStreamBuffer ); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) { - ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, - ( uint32_t ) 0, - eNoAction, - pxHigherPriorityTaskWoken ); + ( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, + ( pxStreamBuffer )->uxNotificationIndex, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); ( pxStreamBuffer )->xTaskWaitingToSend = NULL; xReturn = pdTRUE; } @@ -1454,7 +1565,7 @@ static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer, static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) { -/* Returns the distance between xTail and xHead. */ + /* Returns the distance between xTail and xHead. */ size_t xCount; xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead; @@ -1489,7 +1600,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, /* The value written just has to be identifiable when looking at the * memory. Don't use 0xA5 as that is the stack fill value and could * result in confusion as to what is actually being observed. */ - #define STREAM_BUFFER_BUFFER_WRITE_VALUE ( 0x55 ) + #define STREAM_BUFFER_BUFFER_WRITE_VALUE ( 0x55 ) configASSERT( memset( pucBuffer, ( int ) STREAM_BUFFER_BUFFER_WRITE_VALUE, xBufferSizeBytes ) == pucBuffer ); } #endif @@ -1499,6 +1610,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, pxStreamBuffer->xLength = xBufferSizeBytes; pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; pxStreamBuffer->ucFlags = ucFlags; + pxStreamBuffer->uxNotificationIndex = tskDEFAULT_INDEX_TO_NOTIFY; #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) { pxStreamBuffer->pxSendCompletedCallback = pxSendCompletedCallback; @@ -1518,8 +1630,43 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, } #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ } +/*-----------------------------------------------------------*/ -#if ( configUSE_TRACE_FACILITY == 1 ) +UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + traceENTER_uxStreamBufferGetStreamBufferNotificationIndex( xStreamBuffer ); + + configASSERT( pxStreamBuffer ); + + traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex( pxStreamBuffer->uxNotificationIndex ); + + return pxStreamBuffer->uxNotificationIndex; +} +/*-----------------------------------------------------------*/ + +void vStreamBufferSetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer, + UBaseType_t uxNotificationIndex ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex ); + + /* There should be no task waiting otherwise we'd never resume them. */ + 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 ); + + pxStreamBuffer->uxNotificationIndex = uxNotificationIndex; + + traceRETURN_vStreamBufferSetStreamBufferNotificationIndex(); +} +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) { @@ -1530,10 +1677,10 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, return xStreamBuffer->uxStreamBufferNumber; } -#endif /* configUSE_TRACE_FACILITY */ + #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ -#if ( configUSE_TRACE_FACILITY == 1 ) + #if ( configUSE_TRACE_FACILITY == 1 ) void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) @@ -1545,10 +1692,10 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, traceRETURN_vStreamBufferSetStreamBufferNumber(); } -#endif /* configUSE_TRACE_FACILITY */ + #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ -#if ( configUSE_TRACE_FACILITY == 1 ) + #if ( configUSE_TRACE_FACILITY == 1 ) uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) { @@ -1559,5 +1706,11 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, return( ( uint8_t ) ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) ); } -#endif /* configUSE_TRACE_FACILITY */ + #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured + * to include stream buffer functionality. This #if is closed at the very bottom + * of this file. If you want to include stream buffers then ensure + * configUSE_STREAM_BUFFERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_STREAM_BUFFERS == 1 */ diff --git a/tasks.c b/tasks.c index 279d4bdb3..1e6ecdc9e 100644 --- a/tasks.c +++ b/tasks.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -41,6 +41,13 @@ #include "timers.h" #include "stack_macros.h" +/* The default definitions are only available for non-MPU ports. The + * reason is that the stack alignment requirements vary for different + * architectures.*/ +#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS != 0 ) ) + #error configKERNEL_PROVIDED_STATIC_MEMORY cannot be set to 1 when using an MPU port. The vApplicationGet*TaskMemory() functions must be provided manually. +#endif + /* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ @@ -136,8 +143,8 @@ #define tskSUSPENDED_CHAR ( 'S' ) /* - * Some kernel aware debuggers require the data the debugger needs access to to - * be global, rather than file scope. + * Some kernel aware debuggers require the data the debugger needs access to be + * global, rather than file scope. */ #ifdef portREMOVE_STATIC_QUALIFIER #define static @@ -149,6 +156,22 @@ #define configIDLE_TASK_NAME "IDLE" #endif +/* Reserve space for Core ID and null termination. */ +#if ( configNUMBER_OF_CORES > 1 ) + /* Multi-core systems with up to 9 cores require 1 character for core ID and 1 for null termination. */ + #if ( configMAX_TASK_NAME_LEN < 2U ) + #error Minimum required task name length is 2. Please increase configMAX_TASK_NAME_LEN. + #endif + #define taskRESERVED_TASK_NAME_LENGTH 2U + +#else /* if ( configNUMBER_OF_CORES > 1 ) */ + /* Reserve space for null termination. */ + #if ( configMAX_TASK_NAME_LEN < 1U ) + #error Minimum required task name length is 1. Please increase configMAX_TASK_NAME_LEN. + #endif + #define taskRESERVED_TASK_NAME_LENGTH 1U +#endif /* if ( ( configNUMBER_OF_CORES > 1 ) */ + #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is @@ -168,17 +191,17 @@ /*-----------------------------------------------------------*/ #if ( configNUMBER_OF_CORES == 1 ) - #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - do { \ - UBaseType_t uxTopPriority = uxTopReadyPriority; \ - \ - /* Find the highest priority queue that contains ready tasks. */ \ - while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ - { \ - configASSERT( uxTopPriority ); \ - --uxTopPriority; \ - } \ - \ + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + do { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) != pdFALSE ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ * the same priority get an equal share of the processor time. */ \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ @@ -248,7 +271,7 @@ pxTemp = pxDelayedTaskList; \ pxDelayedTaskList = pxOverflowDelayedTaskList; \ pxOverflowDelayedTaskList = pxTemp; \ - xNumOfOverflows++; \ + xNumOfOverflows = ( BaseType_t ) ( xNumOfOverflows + 1 ); \ prvResetNextTaskUnblockTime(); \ } while( 0 ) @@ -286,9 +309,9 @@ #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #define taskEVENT_LIST_ITEM_VALUE_IN_USE ( ( uint16_t ) 0x8000U ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - #define taskEVENT_LIST_ITEM_VALUE_IN_USE ( ( uint32_t ) 0x80000000UL ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE ( ( uint32_t ) 0x80000000U ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) - #define taskEVENT_LIST_ITEM_VALUE_IN_USE ( ( uint64_t ) 0x8000000000000000ULL ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE ( ( uint64_t ) 0x8000000000000000U ) #endif /* Indicates that the task is not actively running on any core. */ @@ -307,13 +330,13 @@ #endif /* Indicates that the task is an Idle task. */ -#define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1UL << 0UL ) +#define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1U << 0U ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) - #define portGET_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting ) - #define portSET_CRITICAL_NESTING_COUNT( x ) ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting = ( x ) ) - #define portINCREMENT_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting++ ) - #define portDECREMENT_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting-- ) + #define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting ) + #define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting = ( x ) ) + #define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting++ ) + #define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting-- ) #endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) */ #define taskBITS_PER_BYTE ( ( size_t ) 8 ) @@ -655,7 +678,8 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, /* * Return the amount of time, in ticks, that will pass before the kernel will - * next move a task from the Blocked state to the Running state. + * next move a task from the Blocked state to the Running state or before the + * tick count overflows (whichever is earlier). * * This conditional compilation should use inequality to 0, not equality to 1. * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user @@ -691,7 +715,7 @@ static void prvResetNextTaskUnblockTime( void ) PRIVILEGED_FUNCTION; */ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, @@ -711,7 +735,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) static TCB_t * prvCreateStaticTask( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -745,7 +769,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) static TCB_t * prvCreateTask( TaskFunction_t pxTaskCode, const char * const pcName, - const configSTACK_DEPTH_TYPE usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; @@ -799,13 +823,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; { UBaseType_t uxPrevCriticalNesting; const TCB_t * pxThisTCB; + BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); /* This must only be called from within a task. */ portASSERT_IF_IN_ISR(); /* This function is always called with interrupts disabled * so this is safe. */ - pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ]; + pxThisTCB = pxCurrentTCBs[ xCoreID ]; while( pxThisTCB->xTaskRunState == taskTASK_SCHEDULED_TO_YIELD ) { @@ -817,12 +842,12 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; * the suspension and critical nesting counts, as well as release * and reacquire the correct locks. And then, do it all over again * if our state changed again during the reacquisition. */ - uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT(); + uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT( xCoreID ); if( uxPrevCriticalNesting > 0U ) { - portSET_CRITICAL_NESTING_COUNT( 0U ); - portRELEASE_ISR_LOCK(); + portSET_CRITICAL_NESTING_COUNT( xCoreID, 0U ); + portRELEASE_ISR_LOCK( xCoreID ); } else { @@ -831,26 +856,29 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; mtCOVERAGE_TEST_MARKER(); } - portRELEASE_TASK_LOCK(); + portRELEASE_TASK_LOCK( xCoreID ); portMEMORY_BARRIER(); configASSERT( pxThisTCB->xTaskRunState == taskTASK_SCHEDULED_TO_YIELD ); portENABLE_INTERRUPTS(); - /* Enabling interrupts should cause this core to immediately - * service the pending interrupt and yield. If the run state is still - * yielding here then that is a problem. */ - configASSERT( pxThisTCB->xTaskRunState != taskTASK_SCHEDULED_TO_YIELD ); + /* Enabling interrupts should cause this core to immediately service + * the pending interrupt and yield. After servicing the pending interrupt, + * the task needs to re-evaluate its run state within this loop, as + * other cores may have requested this task to yield, potentially altering + * its run state. */ portDISABLE_INTERRUPTS(); - portGET_TASK_LOCK(); - portGET_ISR_LOCK(); - portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting ); + xCoreID = ( BaseType_t ) portGET_CORE_ID(); + portGET_TASK_LOCK( xCoreID ); + portGET_ISR_LOCK( xCoreID ); + + portSET_CRITICAL_NESTING_COUNT( xCoreID, uxPrevCriticalNesting ); if( uxPrevCriticalNesting == 0U ) { - portRELEASE_ISR_LOCK(); + portRELEASE_ISR_LOCK( xCoreID ); } } } @@ -865,13 +893,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; BaseType_t xCurrentCoreTaskPriority; BaseType_t xLowestPriorityCore = ( BaseType_t ) -1; BaseType_t xCoreID; + const BaseType_t xCurrentCoreID = ( BaseType_t ) portGET_CORE_ID(); #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) BaseType_t xYieldCount = 0; #endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ /* This must be called from a critical section. */ - configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U ); + configASSERT( portGET_CRITICAL_NESTING_COUNT( xCurrentCoreID ) > 0U ); #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) @@ -896,7 +925,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* System idle tasks are being assigned a priority of tskIDLE_PRIORITY - 1 here. */ if( ( pxCurrentTCBs[ xCoreID ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) { - xCurrentCoreTaskPriority = xCurrentCoreTaskPriority - 1; + xCurrentCoreTaskPriority = ( BaseType_t ) ( xCurrentCoreTaskPriority - 1 ); } if( ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCoreID ] ) != pdFALSE ) && ( xYieldPendings[ xCoreID ] == pdFALSE ) ) @@ -960,11 +989,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) /* Verify that the calling core always yields to higher priority tasks. */ - if( ( ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0U ) && - ( pxTCB->uxPriority > pxCurrentTCBs[ portGET_CORE_ID() ]->uxPriority ) ) + if( ( ( pxCurrentTCBs[ xCurrentCoreID ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0U ) && + ( pxTCB->uxPriority > pxCurrentTCBs[ xCurrentCoreID ]->uxPriority ) ) { - configASSERT( ( xYieldPendings[ portGET_CORE_ID() ] == pdTRUE ) || - ( taskTASK_IS_RUNNING( pxCurrentTCBs[ portGET_CORE_ID() ] ) == pdFALSE ) ); + configASSERT( ( xYieldPendings[ xCurrentCoreID ] == pdTRUE ) || + ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCurrentCoreID ] ) == pdFALSE ) ); } #endif } @@ -978,6 +1007,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; UBaseType_t uxCurrentPriority = uxTopReadyPriority; BaseType_t xTaskScheduled = pdFALSE; BaseType_t xDecrementTopPriority = pdTRUE; + TCB_t * pxTCB = NULL; #if ( configUSE_CORE_AFFINITY == 1 ) const TCB_t * pxPreviousTCB = NULL; @@ -1036,7 +1066,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* MISRA Ref 11.5.3 [Void pointer assignment] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ /* coverity[misra_c_2012_rule_11_5_violation] */ - TCB_t * pxTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxIterator ); + pxTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxIterator ); #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) { @@ -1245,7 +1275,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static TCB_t * prvCreateStaticTask( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -1287,7 +1317,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; } #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ - prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvInitialiseNewTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); } else { @@ -1300,7 +1330,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -1309,16 +1339,16 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; TaskHandle_t xReturn = NULL; TCB_t * pxNewTCB; - traceENTER_xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + traceENTER_xTaskCreateStatic( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); - pxNewTCB = prvCreateStaticTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, &xReturn ); + pxNewTCB = prvCreateStaticTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, &xReturn ); if( pxNewTCB != NULL ) { #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) { /* Set the task's affinity before scheduling it. */ - pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; + pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY; } #endif @@ -1338,7 +1368,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) TaskHandle_t xTaskCreateStaticAffinitySet( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, @@ -1348,9 +1378,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; TaskHandle_t xReturn = NULL; TCB_t * pxNewTCB; - traceENTER_xTaskCreateStaticAffinitySet( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask ); + traceENTER_xTaskCreateStaticAffinitySet( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask ); - pxNewTCB = prvCreateStaticTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, &xReturn ); + pxNewTCB = prvCreateStaticTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, &xReturn ); if( pxNewTCB != NULL ) { @@ -1403,7 +1433,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, pxTaskDefinition->pcName, - ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->usStackDepth, pxTaskDefinition->pvParameters, pxTaskDefinition->uxPriority, pxCreatedTask, pxNewTCB, @@ -1435,7 +1465,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) { /* Set the task's affinity before scheduling it. */ - pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; + pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY; } #endif @@ -1522,7 +1552,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, pxTaskDefinition->pcName, - ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->usStackDepth, pxTaskDefinition->pvParameters, pxTaskDefinition->uxPriority, pxCreatedTask, pxNewTCB, @@ -1553,7 +1583,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) { /* Set the task's affinity before scheduling it. */ - pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; + pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY; } #endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */ @@ -1611,7 +1641,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) static TCB_t * prvCreateTask( TaskFunction_t pxTaskCode, const char * const pcName, - const configSTACK_DEPTH_TYPE usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) @@ -1641,7 +1671,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* MISRA Ref 11.5.1 [Malloc memory assignment] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ /* coverity[misra_c_2012_rule_11_5_violation] */ - pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); + pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) ); if( pxNewTCB->pxStack == NULL ) { @@ -1659,7 +1689,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* MISRA Ref 11.5.1 [Malloc memory assignment] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ /* coverity[misra_c_2012_rule_11_5_violation] */ - pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); + pxStack = pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) ); if( pxStack != NULL ) { @@ -1700,7 +1730,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; } #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ - prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvInitialiseNewTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); } return pxNewTCB; @@ -1709,7 +1739,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, - const configSTACK_DEPTH_TYPE usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) @@ -1717,16 +1747,16 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; TCB_t * pxNewTCB; BaseType_t xReturn; - traceENTER_xTaskCreate( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + traceENTER_xTaskCreate( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask ); - pxNewTCB = prvCreateTask( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + pxNewTCB = prvCreateTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask ); if( pxNewTCB != NULL ) { #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) { /* Set the task's affinity before scheduling it. */ - pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; + pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY; } #endif @@ -1747,7 +1777,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) BaseType_t xTaskCreateAffinitySet( TaskFunction_t pxTaskCode, const char * const pcName, - const configSTACK_DEPTH_TYPE usStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, UBaseType_t uxCoreAffinityMask, @@ -1756,9 +1786,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; TCB_t * pxNewTCB; BaseType_t xReturn; - traceENTER_xTaskCreateAffinitySet( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask ); + traceENTER_xTaskCreateAffinitySet( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask ); - pxNewTCB = prvCreateTask( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + pxNewTCB = prvCreateTask( pxTaskCode, pcName, uxStackDepth, pvParameters, uxPriority, pxCreatedTask ); if( pxNewTCB != NULL ) { @@ -1784,7 +1814,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, const char * const pcName, - const uint32_t ulStackDepth, + const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, @@ -1813,7 +1843,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #if ( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) { /* Fill the stack with a known value to assist debugging. */ - ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) uxStackDepth * sizeof( StackType_t ) ); } #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */ @@ -1823,11 +1853,11 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * by the port. */ #if ( portSTACK_GROWTH < 0 ) { - pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] ); + pxTopOfStack = &( pxNewTCB->pxStack[ uxStackDepth - ( configSTACK_DEPTH_TYPE ) 1 ] ); pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /* Check the alignment of the calculated top of stack is correct. */ - configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0U ) ); #if ( configRECORD_STACK_HIGH_ADDRESS == 1 ) { @@ -1843,11 +1873,11 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) + portBYTE_ALIGNMENT_MASK ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /* Check the alignment of the calculated top of stack is correct. */ - configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0U ) ); /* The other extreme of the stack space is required if stack checking is * performed. */ - pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( uxStackDepth - ( configSTACK_DEPTH_TYPE ) 1 ); } #endif /* portSTACK_GROWTH */ @@ -1912,7 +1942,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #if ( portUSING_MPU_WRAPPERS == 1 ) { - vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); + vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, uxStackDepth ); } #else { @@ -1986,7 +2016,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, pxNewTCB->xTaskRunState = taskTASK_NOT_RUNNING; /* Is this an idle task? */ - if( ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvIdleTask ) || ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvPassiveIdleTask ) ) + if( ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) ( &prvIdleTask ) ) || ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) ( &prvPassiveIdleTask ) ) ) { pxNewTCB->uxTaskAttributes |= taskATTRIBUTE_IS_IDLE; } @@ -2014,7 +2044,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * updated. */ taskENTER_CRITICAL(); { - uxCurrentNumberOfTasks++; + uxCurrentNumberOfTasks = ( UBaseType_t ) ( uxCurrentNumberOfTasks + 1U ); if( pxCurrentTCB == NULL ) { @@ -2108,29 +2138,9 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, mtCOVERAGE_TEST_MARKER(); } - if( ( pxNewTCB->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) != 0U ) - { - BaseType_t xCoreID; - - /* Check if a core is free. */ - for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) - { - if( pxCurrentTCBs[ xCoreID ] == NULL ) - { - pxNewTCB->xTaskRunState = xCoreID; - pxCurrentTCBs[ xCoreID ] = pxNewTCB; - break; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* All the cores start with idle tasks before the SMP scheduler + * is running. Idle tasks are assigned to cores when they are + * created in prvCreateIdleTasks(). */ } uxTaskNumber++; @@ -2203,6 +2213,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, void vTaskDelete( TaskHandle_t xTaskToDelete ) { TCB_t * pxTCB; + BaseType_t xDeleteTCBInIdleTask = pdFALSE; + BaseType_t xTaskIsRunningOrYielding; traceENTER_vTaskDelete( xTaskToDelete ); @@ -2211,6 +2223,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the calling task that is * being deleted. */ pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + configASSERT( pxTCB != NULL ); /* Remove task from the ready/delayed list. */ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) @@ -2238,10 +2251,15 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * not return. */ uxTaskNumber++; + /* Use temp variable as distinct sequence points for reading volatile + * variables prior to a logical operator to ensure compliance with + * MISRA C 2012 Rule 13.5. */ + xTaskIsRunningOrYielding = taskTASK_IS_RUNNING_OR_SCHEDULED_TO_YIELD( pxTCB ); + /* If the task is running (or yielding), we must add it to the * termination list so that an idle task can delete it when it is * no longer running. */ - if( taskTASK_IS_RUNNING_OR_SCHEDULED_TO_YIELD( pxTCB ) != pdFALSE ) + if( ( xSchedulerRunning != pdFALSE ) && ( xTaskIsRunningOrYielding != pdFALSE ) ) { /* A running task or a task which is scheduled to yield is being * deleted. This cannot complete when the task is still running @@ -2260,6 +2278,9 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * portPRE_TASK_DELETE_HOOK() does not return in the Win32 port. */ traceTASK_DELETE( pxTCB ); + /* Delete the task TCB in idle task. */ + xDeleteTCBInIdleTask = pdTRUE; + /* The pre-delete hook is primarily for the Windows simulator, * in which Windows specific clean up operations are performed, * after which it is not possible to yield away from this task - @@ -2270,6 +2291,30 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #else portPRE_TASK_DELETE_HOOK( pxTCB, &( xYieldPendings[ pxTCB->xTaskRunState ] ) ); #endif + + /* In the case of SMP, it is possible that the task being deleted + * is running on another core. We must evict the task before + * exiting the critical section to ensure that the task cannot + * take an action which puts it back on ready/state/event list, + * thereby nullifying the delete operation. Once evicted, the + * task won't be scheduled ever as it will no longer be on the + * ready list. */ + #if ( configNUMBER_OF_CORES > 1 ) + { + if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) + { + if( pxTCB->xTaskRunState == ( BaseType_t ) portGET_CORE_ID() ) + { + configASSERT( uxSchedulerSuspended == 0 ); + taskYIELD_WITHIN_API(); + } + else + { + prvYieldCore( pxTCB->xTaskRunState ); + } + } + } + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ } else { @@ -2281,27 +2326,26 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, prvResetNextTaskUnblockTime(); } } + taskEXIT_CRITICAL(); + /* If the task is not deleting itself, call prvDeleteTCB from outside of + * critical section. If a task deletes itself, prvDeleteTCB is called + * from prvCheckTasksWaitingTermination which is called from Idle task. */ + if( xDeleteTCBInIdleTask != pdTRUE ) + { + prvDeleteTCB( pxTCB ); + } + + /* Force a reschedule if it is the currently running task that has just + * been deleted. */ #if ( configNUMBER_OF_CORES == 1 ) { - taskEXIT_CRITICAL(); - - /* If the task is not deleting itself, call prvDeleteTCB from outside of - * critical section. If a task deletes itself, prvDeleteTCB is called - * from prvCheckTasksWaitingTermination which is called from Idle task. */ - if( pxTCB != pxCurrentTCB ) - { - prvDeleteTCB( pxTCB ); - } - - /* Force a reschedule if it is the currently running task that has just - * been deleted. */ if( xSchedulerRunning != pdFALSE ) { if( pxTCB == pxCurrentTCB ) { configASSERT( uxSchedulerSuspended == 0 ); - portYIELD_WITHIN_API(); + taskYIELD_WITHIN_API(); } else { @@ -2309,32 +2353,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, } } } - #else /* #if ( configNUMBER_OF_CORES == 1 ) */ - { - /* If a running task is not deleting itself, call prvDeleteTCB. If a running - * task deletes itself, prvDeleteTCB is called from prvCheckTasksWaitingTermination - * which is called from Idle task. */ - if( pxTCB->xTaskRunState == taskTASK_NOT_RUNNING ) - { - prvDeleteTCB( pxTCB ); - } - - /* Force a reschedule if the task that has just been deleted was running. */ - if( ( xSchedulerRunning != pdFALSE ) && ( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) ) - { - if( pxTCB->xTaskRunState == ( BaseType_t ) portGET_CORE_ID() ) - { - configASSERT( uxSchedulerSuspended == 0 ); - vTaskYieldWithinAPI(); - } - else - { - prvYieldCore( pxTCB->xTaskRunState ); - } - } - - taskEXIT_CRITICAL(); - } #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ traceRETURN_vTaskDelete(); @@ -2498,7 +2516,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, traceENTER_eTaskGetState( xTask ); - configASSERT( pxTCB ); + configASSERT( pxTCB != NULL ); #if ( configNUMBER_OF_CORES == 1 ) if( pxTCB == pxCurrentTCB ) @@ -2626,14 +2644,16 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, traceENTER_uxTaskPriorityGet( xTask ); - taskENTER_CRITICAL(); + portBASE_TYPE_ENTER_CRITICAL(); { /* If null is passed in here then it is the priority of the task * that called uxTaskPriorityGet() that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxPriority; } - taskEXIT_CRITICAL(); + portBASE_TYPE_EXIT_CRITICAL(); traceRETURN_uxTaskPriorityGet( uxReturn ); @@ -2671,11 +2691,16 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { /* If null is passed in here then it is the priority of the calling * task that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxPriority; } taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); @@ -2697,14 +2722,16 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, traceENTER_uxTaskBasePriorityGet( xTask ); - taskENTER_CRITICAL(); + portBASE_TYPE_ENTER_CRITICAL(); { /* If null is passed in here then it is the base priority of the task * that called uxTaskBasePriorityGet() that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxBasePriority; } - taskEXIT_CRITICAL(); + portBASE_TYPE_EXIT_CRITICAL(); traceRETURN_uxTaskBasePriorityGet( uxReturn ); @@ -2742,11 +2769,16 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { /* If null is passed in here then it is the base priority of the calling * task that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxBasePriority; } taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); @@ -2791,6 +2823,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the priority of the calling * task that is being changed. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); @@ -2890,7 +2923,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* Only reset the event list item value if the value is not * being used for anything else. */ - if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0UL ) ) + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0U ) ) { listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); } @@ -2979,19 +3012,14 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { TCB_t * pxTCB; BaseType_t xCoreID; - UBaseType_t uxPrevCoreAffinityMask; - - #if ( configUSE_PREEMPTION == 1 ) - UBaseType_t uxPrevNotAllowedCores; - #endif traceENTER_vTaskCoreAffinitySet( xTask, uxCoreAffinityMask ); taskENTER_CRITICAL(); { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); - uxPrevCoreAffinityMask = pxTCB->uxCoreAffinityMask; pxTCB->uxCoreAffinityMask = uxCoreAffinityMask; if( xSchedulerRunning != pdFALSE ) @@ -3011,17 +3039,14 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { #if ( configUSE_PREEMPTION == 1 ) { - /* Calculate the cores on which this task was not allowed to - * run previously. */ - uxPrevNotAllowedCores = ( ~uxPrevCoreAffinityMask ) & ( ( 1U << configNUMBER_OF_CORES ) - 1U ); - - /* Does the new core mask enables this task to run on any of the - * previously not allowed cores? If yes, check if this task can be - * scheduled on any of those cores. */ - if( ( uxPrevNotAllowedCores & uxCoreAffinityMask ) != 0U ) - { - prvYieldForTask( pxTCB ); - } + /* The SMP scheduler requests a core to yield when a ready + * task is able to run. It is possible that the core affinity + * of the ready task is changed before the requested core + * can select it to run. In that case, the task may not be + * selected by the previously requested core due to core affinity + * constraint and the SMP scheduler must select a new core to + * yield for the task. */ + prvYieldForTask( xTask ); } #else /* #if( configUSE_PREEMPTION == 1 ) */ { @@ -3046,12 +3071,14 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, traceENTER_vTaskCoreAffinityGet( xTask ); - taskENTER_CRITICAL(); + portBASE_TYPE_ENTER_CRITICAL(); { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxCoreAffinityMask = pxTCB->uxCoreAffinityMask; } - taskEXIT_CRITICAL(); + portBASE_TYPE_EXIT_CRITICAL(); traceRETURN_vTaskCoreAffinityGet( uxCoreAffinityMask ); @@ -3072,6 +3099,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, taskENTER_CRITICAL(); { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); pxTCB->xPreemptionDisable = pdTRUE; } @@ -3095,6 +3123,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, taskENTER_CRITICAL(); { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); pxTCB->xPreemptionDisable = pdFALSE; @@ -3121,10 +3150,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { TCB_t * pxTCB; - #if ( configNUMBER_OF_CORES > 1 ) - BaseType_t xTaskRunningOnCore; - #endif - traceENTER_vTaskSuspend( xTaskToSuspend ); taskENTER_CRITICAL(); @@ -3132,13 +3157,10 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the running task that is * being suspended. */ pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + configASSERT( pxTCB != NULL ); traceTASK_SUSPEND( pxTCB ); - #if ( configNUMBER_OF_CORES > 1 ) - xTaskRunningOnCore = pxTCB->xTaskRunState; - #endif - /* Remove task from the ready/delayed list and place in the * suspended list. */ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) @@ -3177,11 +3199,52 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, } } #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ + + /* In the case of SMP, it is possible that the task being suspended + * is running on another core. We must evict the task before + * exiting the critical section to ensure that the task cannot + * take an action which puts it back on ready/state/event list, + * thereby nullifying the suspend operation. Once evicted, the + * task won't be scheduled before it is resumed as it will no longer + * be on the ready list. */ + #if ( configNUMBER_OF_CORES > 1 ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* Reset the next expected unblock time in case it referred to the + * task that is now in the Suspended state. */ + prvResetNextTaskUnblockTime(); + + if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) + { + if( pxTCB->xTaskRunState == ( BaseType_t ) portGET_CORE_ID() ) + { + /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == 0 ); + vTaskYieldWithinAPI(); + } + else + { + prvYieldCore( pxTCB->xTaskRunState ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ } + taskEXIT_CRITICAL(); #if ( configNUMBER_OF_CORES == 1 ) { - taskEXIT_CRITICAL(); + UBaseType_t uxCurrentListLength; if( xSchedulerRunning != pdFALSE ) { @@ -3211,7 +3274,13 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* The scheduler is not running, but the task that was pointed * to by pxCurrentTCB has just been suspended and pxCurrentTCB * must be adjusted to point to a different task. */ - if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) + + /* Use a temp variable as a distinct sequence point for reading + * volatile variables prior to a comparison to ensure compliance + * with MISRA C 2012 Rule 13.2. */ + uxCurrentListLength = listCURRENT_LIST_LENGTH( &xSuspendedTaskList ); + + if( uxCurrentListLength == uxCurrentNumberOfTasks ) { /* No other tasks are ready, so set pxCurrentTCB back to * NULL so when the next task is created pxCurrentTCB will @@ -3230,51 +3299,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, mtCOVERAGE_TEST_MARKER(); } } - #else /* #if ( configNUMBER_OF_CORES == 1 ) */ - { - if( xSchedulerRunning != pdFALSE ) - { - /* Reset the next expected unblock time in case it referred to the - * task that is now in the Suspended state. */ - prvResetNextTaskUnblockTime(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) - { - if( xSchedulerRunning != pdFALSE ) - { - if( xTaskRunningOnCore == ( BaseType_t ) portGET_CORE_ID() ) - { - /* The current task has just been suspended. */ - configASSERT( uxSchedulerSuspended == 0 ); - vTaskYieldWithinAPI(); - } - else - { - prvYieldCore( xTaskRunningOnCore ); - } - } - else - { - /* This code path is not possible because only Idle tasks are - * assigned a core before the scheduler is started ( i.e. - * taskTASK_IS_RUNNING is only true for idle tasks before - * the scheduler is started ) and idle tasks cannot be - * suspended. */ - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - taskEXIT_CRITICAL(); - } #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ traceRETURN_vTaskSuspend(); @@ -3444,6 +3468,9 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) @@ -3514,17 +3541,20 @@ static BaseType_t prvCreateIdleTasks( void ) { BaseType_t xReturn = pdPASS; BaseType_t xCoreID; - char cIdleName[ configMAX_TASK_NAME_LEN ]; + char cIdleName[ configMAX_TASK_NAME_LEN ] = { 0 }; TaskFunction_t pxIdleTaskFunction = NULL; - BaseType_t xIdleTaskNameIndex; + UBaseType_t xIdleTaskNameIndex; - for( xIdleTaskNameIndex = ( BaseType_t ) 0; xIdleTaskNameIndex < ( BaseType_t ) configMAX_TASK_NAME_LEN; xIdleTaskNameIndex++ ) + /* MISRA Ref 14.3.1 [Configuration dependent invariant] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-143. */ + /* coverity[misra_c_2012_rule_14_3_violation] */ + for( xIdleTaskNameIndex = 0U; xIdleTaskNameIndex < ( configMAX_TASK_NAME_LEN - taskRESERVED_TASK_NAME_LENGTH ); xIdleTaskNameIndex++ ) { + /* MISRA Ref 18.1.1 [Configuration dependent bounds checking] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-181. */ + /* coverity[misra_c_2012_rule_18_1_violation] */ cIdleName[ xIdleTaskNameIndex ] = configIDLE_TASK_NAME[ xIdleTaskNameIndex ]; - /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than - * configMAX_TASK_NAME_LEN characters just in case the memory after the - * string is not accessible (extremely unlikely). */ if( cIdleName[ xIdleTaskNameIndex ] == ( char ) 0x00 ) { break; @@ -3535,12 +3565,15 @@ static BaseType_t prvCreateIdleTasks( void ) } } + /* Ensure null termination. */ + cIdleName[ xIdleTaskNameIndex ] = '\0'; + /* Add each idle task at the lowest priority. */ for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) { #if ( configNUMBER_OF_CORES == 1 ) { - pxIdleTaskFunction = prvIdleTask; + pxIdleTaskFunction = &prvIdleTask; } #else /* #if ( configNUMBER_OF_CORES == 1 ) */ { @@ -3549,11 +3582,11 @@ static BaseType_t prvCreateIdleTasks( void ) * run when no other task is available to run. */ if( xCoreID == 0 ) { - pxIdleTaskFunction = prvIdleTask; + pxIdleTaskFunction = &prvIdleTask; } else { - pxIdleTaskFunction = prvPassiveIdleTask; + pxIdleTaskFunction = &prvPassiveIdleTask; } } #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ @@ -3563,25 +3596,14 @@ static BaseType_t prvCreateIdleTasks( void ) * only one idle task. */ #if ( configNUMBER_OF_CORES > 1 ) { - /* Append the idle task number to the end of the name if there is space. */ - if( xIdleTaskNameIndex < ( BaseType_t ) configMAX_TASK_NAME_LEN ) - { - cIdleName[ xIdleTaskNameIndex ] = ( char ) ( xCoreID + '0' ); - - /* And append a null character if there is space. */ - if( ( xIdleTaskNameIndex + 1 ) < ( BaseType_t ) configMAX_TASK_NAME_LEN ) - { - cIdleName[ xIdleTaskNameIndex + 1 ] = '\0'; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* Append the idle task number to the end of the name. + * + * Note: Idle task name index only supports single-character + * core IDs (0-9). If the core ID exceeds 9, the idle task + * name will contain an incorrect ASCII character. This is + * acceptable as the task name is used mainly for debugging. */ + cIdleName[ xIdleTaskNameIndex ] = ( char ) ( xCoreID + '0' ); + cIdleName[ xIdleTaskNameIndex + 1U ] = '\0'; } #endif /* if ( configNUMBER_OF_CORES > 1 ) */ @@ -3589,29 +3611,29 @@ static BaseType_t prvCreateIdleTasks( void ) { StaticTask_t * pxIdleTaskTCBBuffer = NULL; StackType_t * pxIdleTaskStackBuffer = NULL; - uint32_t ulIdleTaskStackSize; + configSTACK_DEPTH_TYPE uxIdleTaskStackSize; /* The Idle task is created using user provided RAM - obtain the * address of the RAM then create the idle task. */ #if ( configNUMBER_OF_CORES == 1 ) { - vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); + vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &uxIdleTaskStackSize ); } #else { if( xCoreID == 0 ) { - vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); + vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &uxIdleTaskStackSize ); } else { - vApplicationGetPassiveIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize, xCoreID - 1 ); + vApplicationGetPassiveIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &uxIdleTaskStackSize, ( BaseType_t ) ( xCoreID - 1 ) ); } } #endif /* if ( configNUMBER_OF_CORES == 1 ) */ xIdleTaskHandles[ xCoreID ] = xTaskCreateStatic( pxIdleTaskFunction, cIdleName, - ulIdleTaskStackSize, + uxIdleTaskStackSize, ( void * ) NULL, portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ pxIdleTaskStackBuffer, @@ -3639,13 +3661,23 @@ static BaseType_t prvCreateIdleTasks( void ) #endif /* configSUPPORT_STATIC_ALLOCATION */ /* Break the loop if any of the idle task is failed to be created. */ - if( xReturn == pdFAIL ) + if( xReturn != pdPASS ) { break; } else { - mtCOVERAGE_TEST_MARKER(); + #if ( configNUMBER_OF_CORES == 1 ) + { + mtCOVERAGE_TEST_MARKER(); + } + #else + { + /* Assign idle task to each core before SMP scheduler is running. */ + xIdleTaskHandles[ xCoreID ]->xTaskRunState = xCoreID; + pxCurrentTCBs[ xCoreID ] = xIdleTaskHandles[ xCoreID ]; + } + #endif } } @@ -3723,6 +3755,8 @@ void vTaskStartScheduler( void ) traceTASK_SWITCHED_IN(); + traceSTARTING_SCHEDULER( xIdleTaskHandles ); + /* Setting up the timer tick is hardware specific and thus in the * portable interface. */ @@ -3761,11 +3795,39 @@ void vTaskEndScheduler( void ) { traceENTER_vTaskEndScheduler(); + #if ( INCLUDE_vTaskDelete == 1 ) + { + BaseType_t xCoreID; + + #if ( configUSE_TIMERS == 1 ) + { + /* Delete the timer task created by the kernel. */ + vTaskDelete( xTimerGetTimerDaemonTaskHandle() ); + } + #endif /* #if ( configUSE_TIMERS == 1 ) */ + + /* Delete Idle tasks created by the kernel.*/ + for( xCoreID = 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) + { + vTaskDelete( xIdleTaskHandles[ xCoreID ] ); + } + + /* Idle task is responsible for reclaiming the resources of the tasks in + * xTasksWaitingTermination list. Since the idle task is now deleted and + * no longer going to run, we need to reclaim resources of all the tasks + * in the xTasksWaitingTermination list. */ + prvCheckTasksWaitingTermination(); + } + #endif /* #if ( INCLUDE_vTaskDelete == 1 ) */ + /* Stop the scheduler interrupts and call the portable scheduler end * routine so the original ISRs can be restored if necessary. The port * layer must ensure interrupts enable bit is left in the correct state. */ portDISABLE_INTERRUPTS(); xSchedulerRunning = pdFALSE; + + /* This function must be called from a task and the application is + * responsible for deleting that task after the scheduler is stopped. */ vPortEndScheduler(); traceRETURN_vTaskEndScheduler(); @@ -3779,9 +3841,30 @@ void vTaskSuspendAll( void ) #if ( configNUMBER_OF_CORES == 1 ) { /* A critical section is not required as the variable is of type - * BaseType_t. Please read Richard Barry's reply in the following link to a - * post in the FreeRTOS support forum before reporting this as a bug! - - * https://goo.gl/wu4acr */ + * BaseType_t. Each task maintains its own context, and a context switch + * cannot occur if the variable is non zero. So, as long as the writing + * from the register back into the memory is atomic, it is not a + * problem. + * + * Consider the following scenario, which starts with + * uxSchedulerSuspended at zero. + * + * 1. load uxSchedulerSuspended into register. + * 2. Now a context switch causes another task to run, and the other + * task uses the same variable. The other task will see the variable + * as zero because the variable has not yet been updated by the + * original task. Eventually the original task runs again. **That can + * only happen when uxSchedulerSuspended is once again zero**. When + * the original task runs again, the contents of the CPU registers + * are restored to exactly how they were when it was switched out - + * therefore the value it read into the register still matches the + * value of the uxSchedulerSuspended variable. + * + * 3. increment register. + * 4. store register into uxSchedulerSuspended. The value restored to + * uxSchedulerSuspended will be the correct value of 1, even though + * the variable was used by other tasks in the mean time. + */ /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that * do not otherwise exhibit real time behaviour. */ @@ -3789,7 +3872,7 @@ void vTaskSuspendAll( void ) /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment * is used to allow calls to vTaskSuspendAll() to nest. */ - ++uxSchedulerSuspended; + uxSchedulerSuspended = ( UBaseType_t ) ( uxSchedulerSuspended + 1U ); /* Enforces ordering for ports and optimised compilers that may otherwise place * the above increment elsewhere. */ @@ -3798,6 +3881,7 @@ void vTaskSuspendAll( void ) #else /* #if ( configNUMBER_OF_CORES == 1 ) */ { UBaseType_t ulState; + BaseType_t xCoreID; /* This must only be called from within a task. */ portASSERT_IF_IN_ISR(); @@ -3811,37 +3895,40 @@ void vTaskSuspendAll( void ) * uxSchedulerSuspended since that will prevent context switches. */ ulState = portSET_INTERRUPT_MASK(); - /* portSOFRWARE_BARRIER() is only implemented for emulated/simulated ports that + xCoreID = ( BaseType_t ) portGET_CORE_ID(); + + /* This must never be called from inside a critical section. */ + configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 ); + + /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that * do not otherwise exhibit real time behaviour. */ portSOFTWARE_BARRIER(); - portGET_TASK_LOCK(); + portGET_TASK_LOCK( xCoreID ); /* uxSchedulerSuspended is increased after prvCheckForRunStateChange. The * purpose is to prevent altering the variable when fromISR APIs are readying * it. */ if( uxSchedulerSuspended == 0U ) { - if( portGET_CRITICAL_NESTING_COUNT() == 0U ) - { - prvCheckForRunStateChange(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + prvCheckForRunStateChange(); } else { mtCOVERAGE_TEST_MARKER(); } - portGET_ISR_LOCK(); + /* Query the coreID again as prvCheckForRunStateChange may have + * caused the task to get scheduled on a different core. The correct + * task lock for the core is acquired in prvCheckForRunStateChange. */ + xCoreID = ( BaseType_t ) portGET_CORE_ID(); + + portGET_ISR_LOCK( xCoreID ); /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment * is used to allow calls to vTaskSuspendAll() to nest. */ ++uxSchedulerSuspended; - portRELEASE_ISR_LOCK(); + portRELEASE_ISR_LOCK( xCoreID ); portCLEAR_INTERRUPT_MASK( ulState ); } @@ -3862,9 +3949,9 @@ void vTaskSuspendAll( void ) static TickType_t prvGetExpectedIdleTime( void ) { TickType_t xReturn; - UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; + BaseType_t xHigherPriorityReadyTasks = pdFALSE; - /* uxHigherPriorityReadyTasks takes care of the case where + /* xHigherPriorityReadyTasks takes care of the case where * configUSE_PREEMPTION is 0, so there may be tasks above the idle priority * task that are in the Ready state, even though the idle task is * running. */ @@ -3872,7 +3959,7 @@ void vTaskSuspendAll( void ) { if( uxTopReadyPriority > tskIDLE_PRIORITY ) { - uxHigherPriorityReadyTasks = pdTRUE; + xHigherPriorityReadyTasks = pdTRUE; } } #else @@ -3886,7 +3973,7 @@ void vTaskSuspendAll( void ) * care of the case where the co-operative scheduler is in use. */ if( uxTopReadyPriority > uxLeastSignificantBit ) { - uxHigherPriorityReadyTasks = pdTRUE; + xHigherPriorityReadyTasks = pdTRUE; } } #endif /* if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) */ @@ -3902,7 +3989,7 @@ void vTaskSuspendAll( void ) * processed. */ xReturn = 0; } - else if( uxHigherPriorityReadyTasks != pdFALSE ) + else if( xHigherPriorityReadyTasks != pdFALSE ) { /* There are tasks in the Ready state that have a priority above the * idle priority. This path can only be reached if @@ -3939,15 +4026,14 @@ BaseType_t xTaskResumeAll( void ) * tasks from this list into their appropriate ready list. */ taskENTER_CRITICAL(); { - BaseType_t xCoreID; - xCoreID = ( BaseType_t ) portGET_CORE_ID(); + const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); /* If uxSchedulerSuspended is zero then this function does not match a * previous call to vTaskSuspendAll(). */ configASSERT( uxSchedulerSuspended != 0U ); - --uxSchedulerSuspended; - portRELEASE_TASK_LOCK(); + uxSchedulerSuspended = ( UBaseType_t ) ( uxSchedulerSuspended - 1U ); + portRELEASE_TASK_LOCK( xCoreID ); if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) { @@ -4146,7 +4232,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /* If null is passed in here then the name of the calling task is being * queried. */ pxTCB = prvGetTCBFromHandle( xTaskToQuery ); - configASSERT( pxTCB ); + configASSERT( pxTCB != NULL ); traceRETURN_pcTaskGetName( &( pxTCB->pcTaskName[ 0 ] ) ); @@ -4155,147 +4241,73 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*-----------------------------------------------------------*/ #if ( INCLUDE_xTaskGetHandle == 1 ) + static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, + const char pcNameToQuery[] ) + { + TCB_t * pxReturn = NULL; + TCB_t * pxTCB = NULL; + UBaseType_t x; + char cNextChar; + BaseType_t xBreakLoop; + const ListItem_t * pxEndMarker = listGET_END_MARKER( pxList ); + ListItem_t * pxIterator; - #if ( configNUMBER_OF_CORES == 1 ) - static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, - const char pcNameToQuery[] ) + /* This function is called with the scheduler suspended. */ + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) { - TCB_t * pxNextTCB; - TCB_t * pxFirstTCB; - TCB_t * pxReturn = NULL; - UBaseType_t x; - char cNextChar; - BaseType_t xBreakLoop; - - /* This function is called with the scheduler suspended. */ - - if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + for( pxIterator = listGET_HEAD_ENTRY( pxList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) ) { /* MISRA Ref 11.5.3 [Void pointer assignment] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ /* coverity[misra_c_2012_rule_11_5_violation] */ - listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + pxTCB = listGET_LIST_ITEM_OWNER( pxIterator ); - do + /* Check each character in the name looking for a match or + * mismatch. */ + xBreakLoop = pdFALSE; + + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) { - /* MISRA Ref 11.5.3 [Void pointer assignment] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + cNextChar = pxTCB->pcTaskName[ x ]; - /* Check each character in the name looking for a match or - * mismatch. */ - xBreakLoop = pdFALSE; - - for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + if( cNextChar != pcNameToQuery[ x ] ) { - cNextChar = pxNextTCB->pcTaskName[ x ]; - - if( cNextChar != pcNameToQuery[ x ] ) - { - /* Characters didn't match. */ - xBreakLoop = pdTRUE; - } - else if( cNextChar == ( char ) 0x00 ) - { - /* Both strings terminated, a match must have been - * found. */ - pxReturn = pxNextTCB; - xBreakLoop = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - if( xBreakLoop != pdFALSE ) - { - break; - } + /* Characters didn't match. */ + xBreakLoop = pdTRUE; + } + else if( cNextChar == ( char ) 0x00 ) + { + /* Both strings terminated, a match must have been + * found. */ + pxReturn = pxTCB; + xBreakLoop = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); } - if( pxReturn != NULL ) + if( xBreakLoop != pdFALSE ) { - /* The handle has been found. */ - break; - } - } while( pxNextTCB != pxFirstTCB ); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - return pxReturn; - } - #else /* if ( configNUMBER_OF_CORES == 1 ) */ - static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, - const char pcNameToQuery[] ) - { - TCB_t * pxReturn = NULL; - UBaseType_t x; - char cNextChar; - BaseType_t xBreakLoop; - const ListItem_t * pxEndMarker = listGET_END_MARKER( pxList ); - ListItem_t * pxIterator; - - /* This function is called with the scheduler suspended. */ - - if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) - { - for( pxIterator = listGET_HEAD_ENTRY( pxList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) ) - { - /* MISRA Ref 11.5.3 [Void pointer assignment] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - TCB_t * pxTCB = listGET_LIST_ITEM_OWNER( pxIterator ); - - /* Check each character in the name looking for a match or - * mismatch. */ - xBreakLoop = pdFALSE; - - for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) - { - cNextChar = pxTCB->pcTaskName[ x ]; - - if( cNextChar != pcNameToQuery[ x ] ) - { - /* Characters didn't match. */ - xBreakLoop = pdTRUE; - } - else if( cNextChar == ( char ) 0x00 ) - { - /* Both strings terminated, a match must have been - * found. */ - pxReturn = pxTCB; - xBreakLoop = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - if( xBreakLoop != pdFALSE ) - { - break; - } - } - - if( pxReturn != NULL ) - { - /* The handle has been found. */ break; } } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - return pxReturn; + if( pxReturn != NULL ) + { + /* The handle has been found. */ + break; + } + } } - #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return pxReturn; + } #endif /* INCLUDE_xTaskGetHandle */ /*-----------------------------------------------------------*/ @@ -4383,6 +4395,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) configASSERT( ppxTaskBuffer != NULL ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 ) { @@ -4622,7 +4635,7 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) traceENTER_xTaskAbortDelay( xTask ); - configASSERT( pxTCB ); + configASSERT( pxTCB != NULL ); vTaskSuspendAll(); { @@ -4650,7 +4663,7 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* This lets the task know it was forcibly removed from the * blocked state so it should not re-evaluate its block time and * then block again. */ - pxTCB->ucDelayAborted = pdTRUE; + pxTCB->ucDelayAborted = ( uint8_t ) pdTRUE; } else { @@ -4715,10 +4728,6 @@ BaseType_t xTaskIncrementTick( void ) TickType_t xItemValue; BaseType_t xSwitchRequired = pdFALSE; - #if ( configUSE_PREEMPTION == 1 ) && ( configNUMBER_OF_CORES > 1 ) - BaseType_t xYieldRequiredForCore[ configNUMBER_OF_CORES ] = { pdFALSE }; - #endif /* #if ( configUSE_PREEMPTION == 1 ) && ( configNUMBER_OF_CORES > 1 ) */ - traceENTER_xTaskIncrementTick(); /* Called by the portable layer each time a tick interrupt occurs. @@ -4870,7 +4879,7 @@ BaseType_t xTaskIncrementTick( void ) { if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCBs[ xCoreID ]->uxPriority ] ) ) > 1U ) { - xYieldRequiredForCore[ xCoreID ] = pdTRUE; + xYieldPendings[ xCoreID ] = pdTRUE; } else { @@ -4922,7 +4931,7 @@ BaseType_t xTaskIncrementTick( void ) if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == pdFALSE ) #endif { - if( ( xYieldRequiredForCore[ xCoreID ] != pdFALSE ) || ( xYieldPendings[ xCoreID ] != pdFALSE ) ) + if( xYieldPendings[ xCoreID ] != pdFALSE ) { if( xCoreID == xCurrentCoreID ) { @@ -4946,7 +4955,7 @@ BaseType_t xTaskIncrementTick( void ) } else { - ++xPendedTicks; + xPendedTicks += 1U; /* The tick hook gets called at regular intervals, even if the * scheduler is locked. */ @@ -5008,6 +5017,7 @@ BaseType_t xTaskIncrementTick( void ) /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ @@ -5037,9 +5047,13 @@ BaseType_t xTaskIncrementTick( void ) /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { xReturn = pxTCB->pxTaskTag; @@ -5189,13 +5203,13 @@ BaseType_t xTaskIncrementTick( void ) * and move on if another core suspended the scheduler. We should only * do that if the current core has suspended the scheduler. */ - portGET_TASK_LOCK(); /* Must always acquire the task lock first. */ - portGET_ISR_LOCK(); + portGET_TASK_LOCK( xCoreID ); /* Must always acquire the task lock first. */ + portGET_ISR_LOCK( xCoreID ); { /* vTaskSwitchContext() must never be called from within a critical section. * This is not necessarily true for single core FreeRTOS, but it is for this * SMP port. */ - configASSERT( portGET_CRITICAL_NESTING_COUNT() == 0 ); + configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 ); if( uxSchedulerSuspended != ( UBaseType_t ) 0U ) { @@ -5271,8 +5285,8 @@ BaseType_t xTaskIncrementTick( void ) #endif } } - portRELEASE_ISR_LOCK(); - portRELEASE_TASK_LOCK(); + portRELEASE_ISR_LOCK( xCoreID ); + portRELEASE_TASK_LOCK( xCoreID ); traceRETURN_vTaskSwitchContext(); } @@ -5591,7 +5605,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, { /* The delay was aborted, which is not the same as a time out, * but has the same result. */ - pxCurrentTCB->ucDelayAborted = pdFALSE; + pxCurrentTCB->ucDelayAborted = ( uint8_t ) pdFALSE; xReturn = pdTRUE; } else @@ -6011,6 +6025,8 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) ( xIndex < ( BaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) { pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB != NULL ); + pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; } else @@ -6038,6 +6054,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) /* If null is passed in here then we are modifying the MPU settings of * the calling task. */ pxTCB = prvGetTCBFromHandle( xTaskToModify ); + configASSERT( pxTCB != NULL ); vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), pxRegions, NULL, 0 ); @@ -6168,6 +6185,7 @@ static void prvCheckTasksWaitingTermination( void ) /* xTask is NULL then get the state of the calling task. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); pxTaskStatus->xHandle = pxTCB; pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName[ 0 ] ); @@ -6197,7 +6215,7 @@ static void prvCheckTasksWaitingTermination( void ) #if ( configGENERATE_RUN_TIME_STATS == 1 ) { - pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; + pxTaskStatus->ulRunTimeCounter = ulTaskGetRunTimeCounter( xTask ); } #else { @@ -6233,21 +6251,25 @@ static void prvCheckTasksWaitingTermination( void ) } else { - BaseType_t x; - - /* The task does not appear on the event list item of - * and of the RTOS objects, but could still be in the - * blocked state if it is waiting on its notification - * rather than waiting on an object. If not, is - * suspended. */ - for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) { - if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) + BaseType_t x; + + /* The task does not appear on the event list item of + * and of the RTOS objects, but could still be in the + * blocked state if it is waiting on its notification + * rather than waiting on an object. If not, is + * suspended. */ + for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) { - pxTaskStatus->eCurrentState = eBlocked; - break; + if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) + { + pxTaskStatus->eCurrentState = eBlocked; + break; + } } } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ } } ( void ) xTaskResumeAll(); @@ -6304,30 +6326,27 @@ static void prvCheckTasksWaitingTermination( void ) List_t * pxList, eTaskState eState ) { - configLIST_VOLATILE TCB_t * pxNextTCB; - configLIST_VOLATILE TCB_t * pxFirstTCB; UBaseType_t uxTask = 0; + const ListItem_t * pxEndMarker = listGET_END_MARKER( pxList ); + ListItem_t * pxIterator; + TCB_t * pxTCB = NULL; if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) { - /* MISRA Ref 11.5.3 [Void pointer assignment] */ - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ - /* coverity[misra_c_2012_rule_11_5_violation] */ - listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); - /* Populate an TaskStatus_t structure within the * pxTaskStatusArray array for each task that is referenced from * pxList. See the definition of TaskStatus_t in task.h for the * meaning of each TaskStatus_t structure member. */ - do + for( pxIterator = listGET_HEAD_ENTRY( pxList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) ) { /* MISRA Ref 11.5.3 [Void pointer assignment] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */ /* coverity[misra_c_2012_rule_11_5_violation] */ - listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); - vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); + pxTCB = listGET_LIST_ITEM_OWNER( pxIterator ); + + vTaskGetInfo( ( TaskHandle_t ) pxTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); uxTask++; - } while( pxNextTCB != pxFirstTCB ); + } } else { @@ -6344,17 +6363,17 @@ static void prvCheckTasksWaitingTermination( void ) static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) { - uint32_t ulCount = 0U; + configSTACK_DEPTH_TYPE uxCount = 0U; while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) { pucStackByte -= portSTACK_GROWTH; - ulCount++; + uxCount++; } - ulCount /= ( uint32_t ) sizeof( StackType_t ); + uxCount /= ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ); - return ( configSTACK_DEPTH_TYPE ) ulCount; + return uxCount; } #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */ @@ -6383,6 +6402,7 @@ static void prvCheckTasksWaitingTermination( void ) * type. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if portSTACK_GROWTH < 0 { @@ -6415,6 +6435,7 @@ static void prvCheckTasksWaitingTermination( void ) traceENTER_uxTaskGetStackHighWaterMark( xTask ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if portSTACK_GROWTH < 0 { @@ -6512,7 +6533,7 @@ static void prvResetNextTaskUnblockTime( void ) } /*-----------------------------------------------------------*/ -#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) || ( configNUMBER_OF_CORES > 1 ) +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_RECURSIVE_MUTEXES == 1 ) ) || ( configNUMBER_OF_CORES > 1 ) #if ( configNUMBER_OF_CORES == 1 ) TaskHandle_t xTaskGetCurrentTaskHandle( void ) @@ -6548,25 +6569,29 @@ static void prvResetNextTaskUnblockTime( void ) return xReturn; } - - TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID ) - { - TaskHandle_t xReturn = NULL; - - traceENTER_xTaskGetCurrentTaskHandleForCore( xCoreID ); - - if( taskVALID_CORE_ID( xCoreID ) != pdFALSE ) - { - xReturn = pxCurrentTCBs[ xCoreID ]; - } - - traceRETURN_xTaskGetCurrentTaskHandleForCore( xReturn ); - - return xReturn; - } #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ -#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ + TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID ) + { + TaskHandle_t xReturn = NULL; + + traceENTER_xTaskGetCurrentTaskHandleForCore( xCoreID ); + + if( taskVALID_CORE_ID( xCoreID ) != pdFALSE ) + { + #if ( configNUMBER_OF_CORES == 1 ) + xReturn = pxCurrentTCB; + #else /* #if ( configNUMBER_OF_CORES == 1 ) */ + xReturn = pxCurrentTCBs[ xCoreID ]; + #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ + } + + traceRETURN_xTaskGetCurrentTaskHandleForCore( xReturn ); + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_RECURSIVE_MUTEXES == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) @@ -6630,7 +6655,7 @@ static void prvResetNextTaskUnblockTime( void ) /* Adjust the mutex holder state to account for its new * priority. Only reset the event list item value if the value is * not being used for anything else. */ - if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0UL ) ) + if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0U ) ) { listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); } @@ -6859,7 +6884,7 @@ static void prvResetNextTaskUnblockTime( void ) /* Only reset the event list item value if the value is not * being used for anything else. */ - if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0UL ) ) + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == ( ( TickType_t ) 0U ) ) { listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse ); } @@ -6934,16 +6959,24 @@ static void prvResetNextTaskUnblockTime( void ) */ void vTaskYieldWithinAPI( void ) { + UBaseType_t ulState; + traceENTER_vTaskYieldWithinAPI(); - if( portGET_CRITICAL_NESTING_COUNT() == 0U ) + ulState = portSET_INTERRUPT_MASK(); { - portYIELD(); - } - else - { - xYieldPendings[ portGET_CORE_ID() ] = pdTRUE; + const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); + + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U ) + { + portYIELD(); + } + else + { + xYieldPendings[ xCoreID ] = pdTRUE; + } } + portCLEAR_INTERRUPT_MASK( ulState ); traceRETURN_vTaskYieldWithinAPI(); } @@ -6992,40 +7025,43 @@ static void prvResetNextTaskUnblockTime( void ) traceENTER_vTaskEnterCritical(); portDISABLE_INTERRUPTS(); - - if( xSchedulerRunning != pdFALSE ) { - if( portGET_CRITICAL_NESTING_COUNT() == 0U ) + const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); + + if( xSchedulerRunning != pdFALSE ) { - portGET_TASK_LOCK(); - portGET_ISR_LOCK(); - } - - portINCREMENT_CRITICAL_NESTING_COUNT(); - - /* This is not the interrupt safe version of the enter critical - * function so assert() if it is being called from an interrupt - * context. Only API functions that end in "FromISR" can be used in an - * interrupt. Only assert if the critical nesting count is 1 to - * protect against recursive calls if the assert function also uses a - * critical section. */ - if( portGET_CRITICAL_NESTING_COUNT() == 1U ) - { - portASSERT_IF_IN_ISR(); - - if( uxSchedulerSuspended == 0U ) + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U ) { - /* The only time there would be a problem is if this is called - * before a context switch and vTaskExitCritical() is called - * after pxCurrentTCB changes. Therefore this should not be - * used within vTaskSwitchContext(). */ - prvCheckForRunStateChange(); + portGET_TASK_LOCK( xCoreID ); + portGET_ISR_LOCK( xCoreID ); + } + + portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ); + + /* This is not the interrupt safe version of the enter critical + * function so assert() if it is being called from an interrupt + * context. Only API functions that end in "FromISR" can be used in an + * interrupt. Only assert if the critical nesting count is 1 to + * protect against recursive calls if the assert function also uses a + * critical section. */ + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 1U ) + { + portASSERT_IF_IN_ISR(); + + if( uxSchedulerSuspended == 0U ) + { + /* The only time there would be a problem is if this is called + * before a context switch and vTaskExitCritical() is called + * after pxCurrentTCB changes. Therefore this should not be + * used within vTaskSwitchContext(). */ + prvCheckForRunStateChange(); + } } } - } - else - { - mtCOVERAGE_TEST_MARKER(); + else + { + mtCOVERAGE_TEST_MARKER(); + } } traceRETURN_vTaskEnterCritical(); @@ -7040,6 +7076,7 @@ static void prvResetNextTaskUnblockTime( void ) UBaseType_t vTaskEnterCriticalFromISR( void ) { UBaseType_t uxSavedInterruptStatus = 0; + const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); traceENTER_vTaskEnterCriticalFromISR(); @@ -7047,12 +7084,12 @@ static void prvResetNextTaskUnblockTime( void ) { uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - if( portGET_CRITICAL_NESTING_COUNT() == 0U ) + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U ) { - portGET_ISR_LOCK(); + portGET_ISR_LOCK( xCoreID ); } - portINCREMENT_CRITICAL_NESTING_COUNT(); + portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ); } else { @@ -7116,31 +7153,33 @@ static void prvResetNextTaskUnblockTime( void ) void vTaskExitCritical( void ) { + const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID(); + traceENTER_vTaskExitCritical(); if( xSchedulerRunning != pdFALSE ) { /* If critical nesting count is zero then this function * does not match a previous call to vTaskEnterCritical(). */ - configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U ); + configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ); /* This function should not be called in ISR. Use vTaskExitCriticalFromISR * to exit critical section from ISR. */ portASSERT_IF_IN_ISR(); - if( portGET_CRITICAL_NESTING_COUNT() > 0U ) + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ) { - portDECREMENT_CRITICAL_NESTING_COUNT(); + portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ); - if( portGET_CRITICAL_NESTING_COUNT() == 0U ) + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U ) { BaseType_t xYieldCurrentTask; /* Get the xYieldPending stats inside the critical section. */ - xYieldCurrentTask = xYieldPendings[ portGET_CORE_ID() ]; + xYieldCurrentTask = xYieldPendings[ xCoreID ]; - portRELEASE_ISR_LOCK(); - portRELEASE_TASK_LOCK(); + portRELEASE_ISR_LOCK( xCoreID ); + portRELEASE_TASK_LOCK( xCoreID ); portENABLE_INTERRUPTS(); /* When a task yields in a critical section it just sets @@ -7177,21 +7216,25 @@ static void prvResetNextTaskUnblockTime( void ) void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ) { + BaseType_t xCoreID; + traceENTER_vTaskExitCriticalFromISR( uxSavedInterruptStatus ); if( xSchedulerRunning != pdFALSE ) { + xCoreID = ( BaseType_t ) portGET_CORE_ID(); + /* If critical nesting count is zero then this function * does not match a previous call to vTaskEnterCritical(). */ - configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U ); + configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ); - if( portGET_CRITICAL_NESTING_COUNT() > 0U ) + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U ) { - portDECREMENT_CRITICAL_NESTING_COUNT(); + portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ); - if( portGET_CRITICAL_NESTING_COUNT() == 0U ) + if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U ) { - portRELEASE_ISR_LOCK(); + portRELEASE_ISR_LOCK( xCoreID ); portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); } else @@ -7474,10 +7517,10 @@ static void prvResetNextTaskUnblockTime( void ) uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); /* For percentage calculations. */ - ulTotalTime /= ( ( configRUN_TIME_COUNTER_TYPE ) 100UL ); + ulTotalTime /= ( ( configRUN_TIME_COUNTER_TYPE ) 100U ); /* Avoid divide by zero errors. */ - if( ulTotalTime > 0UL ) + if( ulTotalTime > 0U ) { /* Create a human readable table from the binary data. */ for( x = 0; x < uxArraySize; x++ ) @@ -7503,7 +7546,7 @@ static void prvResetNextTaskUnblockTime( void ) * character. */ if( uxConsumedBufferLength < ( uxBufferLength - 1U ) ) { - if( ulStatsAsPercentage > 0UL ) + if( ulStatsAsPercentage > 0U ) { #ifdef portLU_PRINTF_SPECIFIER_REQUIRED { @@ -7650,95 +7693,78 @@ TickType_t uxTaskResetEventItemValue( void ) TickType_t xTicksToWait ) { uint32_t ulReturn; - BaseType_t xAlreadyYielded; + BaseType_t xAlreadyYielded, xShouldBlock = pdFALSE; traceENTER_ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); configASSERT( uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES ); - taskENTER_CRITICAL(); - - /* Only block if the notification count is not already non-zero. */ - if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0UL ) + /* If the notification count is zero, and if we are willing to wait for a + * notification, then block the task and wait. */ + if( ( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0U ) && ( xTicksToWait > ( TickType_t ) 0 ) ) { - /* Mark this task as waiting for a notification. */ - pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; - - if( xTicksToWait > ( TickType_t ) 0 ) + /* We suspend the scheduler here as prvAddCurrentTaskToDelayedList is a + * non-deterministic operation. */ + vTaskSuspendAll(); { - traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWaitOn ); - - /* We MUST suspend the scheduler before exiting the critical - * section (i.e. before enabling interrupts). - * - * If we do not do so, a notification sent from an ISR, which - * happens after exiting the critical section and before - * suspending the scheduler, will get lost. The sequence of - * events will be: - * 1. Exit critical section. - * 2. Interrupt - ISR calls xTaskNotifyFromISR which adds the - * task to the Ready list. - * 3. Suspend scheduler. - * 4. prvAddCurrentTaskToDelayedList moves the task to the - * delayed or suspended list. - * 5. Resume scheduler does not touch the task (because it is - * not on the pendingReady list), effectively losing the - * notification from the ISR. - * - * The same does not happen when we suspend the scheduler before - * exiting the critical section. The sequence of events in this - * case will be: - * 1. Suspend scheduler. - * 2. Exit critical section. - * 3. Interrupt - ISR calls xTaskNotifyFromISR which adds the - * task to the pendingReady list as the scheduler is - * suspended. - * 4. prvAddCurrentTaskToDelayedList adds the task to delayed or - * suspended list. Note that this operation does not nullify - * the add to pendingReady list done in the above step because - * a different list item, namely xEventListItem, is used for - * adding the task to the pendingReady list. In other words, - * the task still remains on the pendingReady list. - * 5. Resume scheduler moves the task from pendingReady list to - * the Ready list. - */ - vTaskSuspendAll(); + /* We MUST enter a critical section to atomically check if a notification + * has occurred and set the flag to indicate that we are waiting for + * a notification. If we do not do so, a notification sent from an ISR + * will get lost. */ + taskENTER_CRITICAL(); { - taskEXIT_CRITICAL(); + /* Only block if the notification count is not already non-zero. */ + if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] == 0U ) + { + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; - prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + /* Arrange to wait for a notification. */ + xShouldBlock = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } - xAlreadyYielded = xTaskResumeAll(); + taskEXIT_CRITICAL(); - if( xAlreadyYielded == pdFALSE ) + /* We are now out of the critical section but the scheduler is still + * suspended, so we are safe to do non-deterministic operations such + * as prvAddCurrentTaskToDelayedList. */ + if( xShouldBlock == pdTRUE ) { - taskYIELD_WITHIN_API(); + traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWaitOn ); + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); } else { mtCOVERAGE_TEST_MARKER(); } } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so. */ + if( ( xShouldBlock == pdTRUE ) && ( xAlreadyYielded == pdFALSE ) ) + { + taskYIELD_WITHIN_API(); + } else { - taskEXIT_CRITICAL(); + mtCOVERAGE_TEST_MARKER(); } } - else - { - taskEXIT_CRITICAL(); - } taskENTER_CRITICAL(); { traceTASK_NOTIFY_TAKE( uxIndexToWaitOn ); ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; - if( ulReturn != 0UL ) + if( ulReturn != 0U ) { if( xClearCountOnExit != pdFALSE ) { - pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = ( uint32_t ) 0UL; + pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] = ( uint32_t ) 0U; } else { @@ -7770,89 +7796,71 @@ TickType_t uxTaskResetEventItemValue( void ) uint32_t * pulNotificationValue, TickType_t xTicksToWait ) { - BaseType_t xReturn, xAlreadyYielded; + BaseType_t xReturn, xAlreadyYielded, xShouldBlock = pdFALSE; traceENTER_xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); configASSERT( uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES ); - taskENTER_CRITICAL(); - - /* Only block if a notification is not already pending. */ - if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) + /* If the task hasn't received a notification, and if we are willing to wait + * for it, then block the task and wait. */ + if( ( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) && ( xTicksToWait > ( TickType_t ) 0 ) ) { - /* Clear bits in the task's notification value as bits may get - * set by the notifying task or interrupt. This can be used to - * clear the value to zero. */ - pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnEntry; - - /* Mark this task as waiting for a notification. */ - pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; - - if( xTicksToWait > ( TickType_t ) 0 ) + /* We suspend the scheduler here as prvAddCurrentTaskToDelayedList is a + * non-deterministic operation. */ + vTaskSuspendAll(); { - traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWaitOn ); - - /* We MUST suspend the scheduler before exiting the critical - * section (i.e. before enabling interrupts). - * - * If we do not do so, a notification sent from an ISR, which - * happens after exiting the critical section and before - * suspending the scheduler, will get lost. The sequence of - * events will be: - * 1. Exit critical section. - * 2. Interrupt - ISR calls xTaskNotifyFromISR which adds the - * task to the Ready list. - * 3. Suspend scheduler. - * 4. prvAddCurrentTaskToDelayedList moves the task to the - * delayed or suspended list. - * 5. Resume scheduler does not touch the task (because it is - * not on the pendingReady list), effectively losing the - * notification from the ISR. - * - * The same does not happen when we suspend the scheduler before - * exiting the critical section. The sequence of events in this - * case will be: - * 1. Suspend scheduler. - * 2. Exit critical section. - * 3. Interrupt - ISR calls xTaskNotifyFromISR which adds the - * task to the pendingReady list as the scheduler is - * suspended. - * 4. prvAddCurrentTaskToDelayedList adds the task to delayed or - * suspended list. Note that this operation does not nullify - * the add to pendingReady list done in the above step because - * a different list item, namely xEventListItem, is used for - * adding the task to the pendingReady list. In other words, - * the task still remains on the pendingReady list. - * 5. Resume scheduler moves the task from pendingReady list to - * the Ready list. - */ - vTaskSuspendAll(); + /* We MUST enter a critical section to atomically check and update the + * task notification value. If we do not do so, a notification from + * an ISR will get lost. */ + taskENTER_CRITICAL(); { - taskEXIT_CRITICAL(); + /* Only block if a notification is not already pending. */ + if( pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] != taskNOTIFICATION_RECEIVED ) + { + /* Clear bits in the task's notification value as bits may get + * set by the notifying task or interrupt. This can be used + * to clear the value to zero. */ + pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ] &= ~ulBitsToClearOnEntry; - prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState[ uxIndexToWaitOn ] = taskWAITING_NOTIFICATION; + + /* Arrange to wait for a notification. */ + xShouldBlock = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } - xAlreadyYielded = xTaskResumeAll(); + taskEXIT_CRITICAL(); - if( xAlreadyYielded == pdFALSE ) + /* We are now out of the critical section but the scheduler is still + * suspended, so we are safe to do non-deterministic operations such + * as prvAddCurrentTaskToDelayedList. */ + if( xShouldBlock == pdTRUE ) { - taskYIELD_WITHIN_API(); + traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWaitOn ); + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); } else { mtCOVERAGE_TEST_MARKER(); } } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so. */ + if( ( xShouldBlock == pdTRUE ) && ( xAlreadyYielded == pdFALSE ) ) + { + taskYIELD_WITHIN_API(); + } else { - taskEXIT_CRITICAL(); + mtCOVERAGE_TEST_MARKER(); } } - else - { - taskEXIT_CRITICAL(); - } taskENTER_CRITICAL(); { @@ -8053,7 +8061,10 @@ TickType_t uxTaskResetEventItemValue( void ) pxTCB = xTaskToNotify; - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { if( pulPreviousNotificationValue != NULL ) { @@ -8119,6 +8130,22 @@ TickType_t uxTaskResetEventItemValue( void ) { listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); + + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked waiting for a notification then + * xNextTaskUnblockTime might be set to the blocked task's time + * out time. If the task is unblocked for a reason other than + * a timeout xNextTaskUnblockTime is normally left unchanged, + * because it will automatically get reset to a new value when + * the tick count equals xNextTaskUnblockTime. However if + * tickless idling is used it might be more important to enter + * sleep mode at the earliest possible time - so reset + * xNextTaskUnblockTime here to ensure it is updated at the + * earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif } else { @@ -8212,7 +8239,10 @@ TickType_t uxTaskResetEventItemValue( void ) pxTCB = xTaskToNotify; - uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + /* MISRA Ref 4.7.1 [Return value shall be checked] */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ + /* coverity[misra_c_2012_directive_4_7_violation] */ + uxSavedInterruptStatus = ( UBaseType_t ) taskENTER_CRITICAL_FROM_ISR(); { ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; @@ -8234,6 +8264,22 @@ TickType_t uxTaskResetEventItemValue( void ) { listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB ); + + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked waiting for a notification then + * xNextTaskUnblockTime might be set to the blocked task's time + * out time. If the task is unblocked for a reason other than + * a timeout xNextTaskUnblockTime is normally left unchanged, + * because it will automatically get reset to a new value when + * the tick count equals xNextTaskUnblockTime. However if + * tickless idling is used it might be more important to enter + * sleep mode at the earliest possible time - so reset + * xNextTaskUnblockTime here to ensure it is updated at the + * earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif } else { @@ -8305,6 +8351,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* If null is passed in here then it is the calling task that is having * its notification state cleared. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); taskENTER_CRITICAL(); { @@ -8344,6 +8391,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* If null is passed in here then it is the calling task that is having * its notification state cleared. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); taskENTER_CRITICAL(); { @@ -8367,14 +8415,37 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) { TCB_t * pxTCB; + configRUN_TIME_COUNTER_TYPE ulTotalTime = 0, ulTimeSinceLastSwitchedIn = 0, ulTaskRunTime = 0; traceENTER_ulTaskGetRunTimeCounter( xTask ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); - traceRETURN_ulTaskGetRunTimeCounter( pxTCB->ulRunTimeCounter ); + taskENTER_CRITICAL(); + { + if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif - return pxTCB->ulRunTimeCounter; + #if ( configNUMBER_OF_CORES == 1 ) + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ 0 ]; + #else + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ pxTCB->xTaskRunState ]; + #endif + } + + ulTaskRunTime = pxTCB->ulRunTimeCounter + ulTimeSinceLastSwitchedIn; + } + taskEXIT_CRITICAL(); + + traceRETURN_ulTaskGetRunTimeCounter( ulTaskRunTime ); + + return ulTaskRunTime; } #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ @@ -8385,11 +8456,17 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) { TCB_t * pxTCB; - configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; + configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn, ulTaskRunTime; traceENTER_ulTaskGetRunTimePercent( xTask ); - ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + ulTaskRunTime = ulTaskGetRunTimeCounter( xTask ); + + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + #endif /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; @@ -8398,7 +8475,9 @@ TickType_t uxTaskResetEventItemValue( void ) if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { pxTCB = prvGetTCBFromHandle( xTask ); - ulReturn = pxTCB->ulRunTimeCounter / ulTotalTime; + configASSERT( pxTCB != NULL ); + + ulReturn = ulTaskRunTime / ulTotalTime; } else { @@ -8417,19 +8496,42 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { - configRUN_TIME_COUNTER_TYPE ulReturn = 0; + configRUN_TIME_COUNTER_TYPE ulTotalTime = 0, ulTimeSinceLastSwitchedIn = 0, ulIdleTaskRunTime = 0; BaseType_t i; traceENTER_ulTaskGetIdleRunTimeCounter(); - for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) + taskENTER_CRITICAL(); { - ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) + { + if( taskTASK_IS_RUNNING( xIdleTaskHandles[ i ] ) == pdTRUE ) + { + #if ( configNUMBER_OF_CORES == 1 ) + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ 0 ]; + #else + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ xIdleTaskHandles[ i ]->xTaskRunState ]; + #endif + } + else + { + ulTimeSinceLastSwitchedIn = 0; + } + + ulIdleTaskRunTime += ( xIdleTaskHandles[ i ]->ulRunTimeCounter + ulTimeSinceLastSwitchedIn ); + } } + taskEXIT_CRITICAL(); - traceRETURN_ulTaskGetIdleRunTimeCounter( ulReturn ); + traceRETURN_ulTaskGetIdleRunTimeCounter( ulIdleTaskRunTime ); - return ulReturn; + return ulIdleTaskRunTime; } #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ @@ -8441,11 +8543,16 @@ TickType_t uxTaskResetEventItemValue( void ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; - BaseType_t i; traceENTER_ulTaskGetIdleRunTimePercent(); - ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + ulTotalTime *= configNUMBER_OF_CORES; /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; @@ -8453,11 +8560,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) - { - ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; - } - + ulRunTimeCounter = ulTaskGetIdleRunTimeCounter(); ulReturn = ulRunTimeCounter / ulTotalTime; } else @@ -8486,7 +8589,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, /* About to enter a delayed list, so ensure the ucDelayAborted flag is * reset to pdFALSE so it can be detected as having been set to pdTRUE * when the task leaves the Blocked state. */ - pxCurrentTCB->ucDelayAborted = pdFALSE; + pxCurrentTCB->ucDelayAborted = ( uint8_t ) pdFALSE; } #endif @@ -8601,6 +8704,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, traceENTER_xTaskGetMPUSettings( xTask ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); traceRETURN_xTaskGetMPUSettings( &( pxTCB->xMPUSettings ) ); @@ -8644,21 +8748,21 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, */ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, - uint32_t * pulIdleTaskStackSize ) + configSTACK_DEPTH_TYPE * puxIdleTaskStackSize ) { static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; *ppxIdleTaskTCBBuffer = &( xIdleTaskTCB ); *ppxIdleTaskStackBuffer = &( uxIdleTaskStack[ 0 ] ); - *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + *puxIdleTaskStackSize = configMINIMAL_STACK_SIZE; } #if ( configNUMBER_OF_CORES > 1 ) void vApplicationGetPassiveIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, - uint32_t * pulIdleTaskStackSize, + configSTACK_DEPTH_TYPE * puxIdleTaskStackSize, BaseType_t xPassiveIdleTaskIndex ) { static StaticTask_t xIdleTaskTCBs[ configNUMBER_OF_CORES - 1 ]; @@ -8666,7 +8770,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, *ppxIdleTaskTCBBuffer = &( xIdleTaskTCBs[ xPassiveIdleTaskIndex ] ); *ppxIdleTaskStackBuffer = &( uxIdleTaskStacks[ xPassiveIdleTaskIndex ][ 0 ] ); - *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + *puxIdleTaskStackSize = configMINIMAL_STACK_SIZE; } #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ @@ -8674,7 +8778,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */ /*-----------------------------------------------------------*/ -#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) +#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) && ( configUSE_TIMERS == 1 ) ) /* * This is the kernel provided implementation of vApplicationGetTimerTaskMemory() @@ -8685,15 +8789,73 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, */ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, - uint32_t * pulTimerTaskStackSize ) + configSTACK_DEPTH_TYPE * puxTimerTaskStackSize ) { static StaticTask_t xTimerTaskTCB; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; *ppxTimerTaskTCBBuffer = &( xTimerTaskTCB ); *ppxTimerTaskStackBuffer = &( uxTimerTaskStack[ 0 ] ); - *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; + *puxTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } -#endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */ +#endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vTaskResetState( void ) +{ + BaseType_t xCoreID; + + /* Task control block. */ + #if ( configNUMBER_OF_CORES == 1 ) + { + pxCurrentTCB = NULL; + } + #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ + + #if ( INCLUDE_vTaskDelete == 1 ) + { + uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; + } + #endif /* #if ( INCLUDE_vTaskDelete == 1 ) */ + + #if ( configUSE_POSIX_ERRNO == 1 ) + { + FreeRTOS_errno = 0; + } + #endif /* #if ( configUSE_POSIX_ERRNO == 1 ) */ + + /* Other file private variables. */ + uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + uxTopReadyPriority = tskIDLE_PRIORITY; + xSchedulerRunning = pdFALSE; + xPendedTicks = ( TickType_t ) 0U; + + for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ ) + { + xYieldPendings[ xCoreID ] = pdFALSE; + } + + xNumOfOverflows = ( BaseType_t ) 0; + uxTaskNumber = ( UBaseType_t ) 0U; + xNextTaskUnblockTime = ( TickType_t ) 0U; + + uxSchedulerSuspended = ( UBaseType_t ) 0U; + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ ) + { + ulTaskSwitchedInTime[ xCoreID ] = 0U; + ulTotalRunTime[ xCoreID ] = 0U; + } + } + #endif /* #if ( configGENERATE_RUN_TIME_STATS == 1 ) */ +} /*-----------------------------------------------------------*/ diff --git a/timers.c b/timers.c index df7f442c3..1bc40bc46 100644 --- a/timers.c +++ b/timers.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -254,12 +254,12 @@ { StaticTask_t * pxTimerTaskTCBBuffer = NULL; StackType_t * pxTimerTaskStackBuffer = NULL; - uint32_t ulTimerTaskStackSize; + configSTACK_DEPTH_TYPE uxTimerTaskStackSize; - vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); - xTimerTaskHandle = xTaskCreateStaticAffinitySet( prvTimerTask, + vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &uxTimerTaskStackSize ); + xTimerTaskHandle = xTaskCreateStaticAffinitySet( &prvTimerTask, configTIMER_SERVICE_TASK_NAME, - ulTimerTaskStackSize, + uxTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, pxTimerTaskStackBuffer, @@ -273,7 +273,7 @@ } #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ { - xReturn = xTaskCreateAffinitySet( prvTimerTask, + xReturn = xTaskCreateAffinitySet( &prvTimerTask, configTIMER_SERVICE_TASK_NAME, configTIMER_TASK_STACK_DEPTH, NULL, @@ -289,12 +289,12 @@ { StaticTask_t * pxTimerTaskTCBBuffer = NULL; StackType_t * pxTimerTaskStackBuffer = NULL; - uint32_t ulTimerTaskStackSize; + configSTACK_DEPTH_TYPE uxTimerTaskStackSize; - vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); - xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, + vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &uxTimerTaskStackSize ); + xTimerTaskHandle = xTaskCreateStatic( &prvTimerTask, configTIMER_SERVICE_TASK_NAME, - ulTimerTaskStackSize, + uxTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, pxTimerTaskStackBuffer, @@ -307,7 +307,7 @@ } #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ { - xReturn = xTaskCreate( prvTimerTask, + xReturn = xTaskCreate( &prvTimerTask, configTIMER_SERVICE_TASK_NAME, configTIMER_TASK_STACK_DEPTH, NULL, @@ -458,11 +458,9 @@ traceENTER_xTimerGenericCommandFromTask( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); - configASSERT( xTimer ); - /* Send a message to the timer service task to perform a particular action * on a particular timer definition. */ - if( xTimerQueue != NULL ) + if( ( xTimerQueue != NULL ) && ( xTimer != NULL ) ) { /* Send a command to the timer service task to start the xTimer timer. */ xMessage.xMessageID = xCommandID; @@ -509,11 +507,9 @@ traceENTER_xTimerGenericCommandFromISR( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); - configASSERT( xTimer ); - /* Send a message to the timer service task to perform a particular action * on a particular timer definition. */ - if( xTimerQueue != NULL ) + if( ( xTimerQueue != NULL ) && ( xTimer != NULL ) ) { /* Send a command to the timer service task to start the xTimer timer. */ xMessage.xMessageID = xCommandID; @@ -601,7 +597,7 @@ traceENTER_xTimerGetReloadMode( xTimer ); configASSERT( xTimer ); - taskENTER_CRITICAL(); + portBASE_TYPE_ENTER_CRITICAL(); { if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0U ) { @@ -614,7 +610,7 @@ xReturn = pdTRUE; } } - taskEXIT_CRITICAL(); + portBASE_TYPE_EXIT_CRITICAL(); traceRETURN_xTimerGetReloadMode( xReturn ); @@ -974,110 +970,117 @@ * software timer. */ pxTimer = xMessage.u.xTimerParameters.pxTimer; - if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) + if( pxTimer != NULL ) { - /* The timer is in a list, remove it. */ - ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + * it must be present in the function call. prvSampleTimeNow() must be + * called after the message is received from xTimerQueue so there is no + * possibility of a higher priority task adding a message to the message + * queue with a time that is ahead of the timer daemon task (because it + * pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START: + case tmrCOMMAND_START_FROM_ISR: + case tmrCOMMAND_RESET: + case tmrCOMMAND_RESET_FROM_ISR: + /* Start or restart a timer. */ + pxTimer->ucStatus |= ( uint8_t ) tmrSTATUS_IS_ACTIVE; + + if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) + { + /* The timer expired before it was added to the active + * timer list. Process it now. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0U ) + { + prvReloadTimer( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow ); + } + else + { + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + } + + /* Call the timer callback. */ + traceTIMER_EXPIRED( pxTimer ); + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + break; + + case tmrCOMMAND_STOP: + case tmrCOMMAND_STOP_FROM_ISR: + /* The timer has already been removed from the active list. */ + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + break; + + case tmrCOMMAND_CHANGE_PERIOD: + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: + pxTimer->ucStatus |= ( uint8_t ) tmrSTATUS_IS_ACTIVE; + pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + + /* The new period does not really have a reference, and can + * be longer or shorter than the old one. The command time is + * therefore set to the current time, and as the period cannot + * be zero the next expiry time can only be in the future, + * meaning (unlike for the xTimerStart() case above) there is + * no fail case that needs to be handled here. */ + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE: + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* The timer has already been removed from the active list, + * just free up the memory if the memory was dynamically + * allocated. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) + { + vPortFree( pxTimer ); + } + else + { + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + } + } + #else /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + { + /* If dynamic allocation is not enabled, the memory + * could not have been dynamically allocated. So there is + * no need to free the memory - just mark the timer as + * "not active". */ + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + break; + + default: + /* Don't expect to get here. */ + break; + } } else { mtCOVERAGE_TEST_MARKER(); } - - traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); - - /* In this case the xTimerListsWereSwitched parameter is not used, but - * it must be present in the function call. prvSampleTimeNow() must be - * called after the message is received from xTimerQueue so there is no - * possibility of a higher priority task adding a message to the message - * queue with a time that is ahead of the timer daemon task (because it - * pre-empted the timer daemon task after the xTimeNow value was set). */ - xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); - - switch( xMessage.xMessageID ) - { - case tmrCOMMAND_START: - case tmrCOMMAND_START_FROM_ISR: - case tmrCOMMAND_RESET: - case tmrCOMMAND_RESET_FROM_ISR: - /* Start or restart a timer. */ - pxTimer->ucStatus |= ( uint8_t ) tmrSTATUS_IS_ACTIVE; - - if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) - { - /* The timer expired before it was added to the active - * timer list. Process it now. */ - if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0U ) - { - prvReloadTimer( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow ); - } - else - { - pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); - } - - /* Call the timer callback. */ - traceTIMER_EXPIRED( pxTimer ); - pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - break; - - case tmrCOMMAND_STOP: - case tmrCOMMAND_STOP_FROM_ISR: - /* The timer has already been removed from the active list. */ - pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); - break; - - case tmrCOMMAND_CHANGE_PERIOD: - case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: - pxTimer->ucStatus |= ( uint8_t ) tmrSTATUS_IS_ACTIVE; - pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; - configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); - - /* The new period does not really have a reference, and can - * be longer or shorter than the old one. The command time is - * therefore set to the current time, and as the period cannot - * be zero the next expiry time can only be in the future, - * meaning (unlike for the xTimerStart() case above) there is - * no fail case that needs to be handled here. */ - ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); - break; - - case tmrCOMMAND_DELETE: - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - /* The timer has already been removed from the active list, - * just free up the memory if the memory was dynamically - * allocated. */ - if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) - { - vPortFree( pxTimer ); - } - else - { - pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); - } - } - #else /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ - { - /* If dynamic allocation is not enabled, the memory - * could not have been dynamically allocated. So there is - * no need to free the memory - just mark the timer as - * "not active". */ - pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); - } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - break; - - default: - /* Don't expect to get here. */ - break; - } } } } @@ -1169,7 +1172,7 @@ configASSERT( xTimer ); /* Is the timer in the list of active timers? */ - taskENTER_CRITICAL(); + portBASE_TYPE_ENTER_CRITICAL(); { if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0U ) { @@ -1180,7 +1183,7 @@ xReturn = pdTRUE; } } - taskEXIT_CRITICAL(); + portBASE_TYPE_EXIT_CRITICAL(); traceRETURN_xTimerIsTimerActive( xReturn ); @@ -1322,6 +1325,18 @@ #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ + void vTimerResetState( void ) + { + xTimerQueue = NULL; + xTimerTaskHandle = NULL; + } +/*-----------------------------------------------------------*/ + /* This entire source file will be skipped if the application is not configured * to include software timer functionality. If you want to include software timer * functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */