mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-03-01 13:35:23 -05:00
Compare commits
58 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1043c49d5 | ||
|
|
0f8efd98cc | ||
|
|
850d29477c | ||
|
|
6cd736cfeb | ||
|
|
d33d04b14c | ||
|
|
67f59a5f58 | ||
|
|
5282247346 | ||
|
|
8a416d79c0 | ||
|
|
d5c3c98ae4 | ||
|
|
c53a6b0547 | ||
|
|
1dbc77697f | ||
|
|
26f9a2fdd3 | ||
|
|
14b30f209f | ||
|
|
3ace38969b | ||
|
|
a9cb459206 | ||
|
|
536914b2a4 | ||
|
|
7d6890e650 | ||
|
|
fed39c5ea7 | ||
|
|
439af33c52 | ||
|
|
c8d31ddcff | ||
|
|
8b63f94d8d | ||
|
|
13074875c2 | ||
|
|
e5987bbdb2 | ||
|
|
a1f6e1f64f | ||
|
|
a8ae21c88e | ||
|
|
3d44975181 | ||
|
|
692c4b070f | ||
|
|
44ae6cf61a | ||
|
|
ccabdec2f8 | ||
|
|
386c1bca66 | ||
|
|
43947413b9 | ||
|
|
c91ee8d724 | ||
|
|
e9440d4079 | ||
|
|
c5bec0e4b2 | ||
|
|
2da35debfd | ||
|
|
32e581636f | ||
|
|
684b34ca8d | ||
|
|
f5e6151b14 | ||
|
|
48a4939c9f | ||
|
|
e3a362b1d1 | ||
|
|
7225fbcbb9 | ||
|
|
a882b10526 | ||
|
|
0ae0715ac9 | ||
|
|
62bd622ffc | ||
|
|
2615dcde13 | ||
|
|
03dc002c9b | ||
|
|
e3a0e3e86a | ||
|
|
4162ca49d6 | ||
|
|
d03233f209 | ||
|
|
4ee6a1f22f | ||
|
|
03db672b8f | ||
|
|
0030d609a4 | ||
|
|
b9aa064591 | ||
|
|
dacce186cf | ||
|
|
64fd9291ef | ||
|
|
bb47bc02f2 | ||
|
|
4d9cd906d3 | ||
|
|
742729ed29 |
169 changed files with 59040 additions and 5806 deletions
26
.github/.cSpellWords.txt
vendored
26
.github/.cSpellWords.txt
vendored
|
|
@ -23,11 +23,13 @@ AIRCR
|
||||||
ALMIEN
|
ALMIEN
|
||||||
ALMV
|
ALMV
|
||||||
ANDC
|
ANDC
|
||||||
|
andi
|
||||||
ANDCCR
|
ANDCCR
|
||||||
APIC
|
APIC
|
||||||
APROCFREQ
|
APROCFREQ
|
||||||
APSR
|
APSR
|
||||||
ARMCM
|
ARMCM
|
||||||
|
ARMEB
|
||||||
Armv
|
Armv
|
||||||
ARMVFP
|
ARMVFP
|
||||||
ASTRINGZ
|
ASTRINGZ
|
||||||
|
|
@ -47,6 +49,7 @@ bcpc
|
||||||
BCPC
|
BCPC
|
||||||
beevt
|
beevt
|
||||||
BEEVT
|
BEEVT
|
||||||
|
beqz
|
||||||
BERR
|
BERR
|
||||||
bfextu
|
bfextu
|
||||||
Biagioni
|
Biagioni
|
||||||
|
|
@ -67,6 +70,7 @@ CANTX
|
||||||
capitalisation
|
capitalisation
|
||||||
cbmc
|
cbmc
|
||||||
CBMC
|
CBMC
|
||||||
|
cbnz
|
||||||
cbor
|
cbor
|
||||||
CBOR
|
CBOR
|
||||||
CCIE
|
CCIE
|
||||||
|
|
@ -105,6 +109,8 @@ CLKS
|
||||||
CLKSOURCE
|
CLKSOURCE
|
||||||
CLKSTA
|
CLKSTA
|
||||||
CLRB
|
CLRB
|
||||||
|
clrex
|
||||||
|
CLREX
|
||||||
CLRF
|
CLRF
|
||||||
clrm
|
clrm
|
||||||
CLRPSW
|
CLRPSW
|
||||||
|
|
@ -298,6 +304,7 @@ FADD
|
||||||
FCMD
|
FCMD
|
||||||
fcolor
|
fcolor
|
||||||
FCSE
|
FCSE
|
||||||
|
fcsr
|
||||||
fdiagnostics
|
fdiagnostics
|
||||||
fdiv
|
fdiv
|
||||||
FDIV
|
FDIV
|
||||||
|
|
@ -375,6 +382,7 @@ IFSR
|
||||||
imajeff
|
imajeff
|
||||||
INACK
|
INACK
|
||||||
INDF
|
INDF
|
||||||
|
initialisations
|
||||||
inpw
|
inpw
|
||||||
INTE
|
INTE
|
||||||
INTFRCH
|
INTFRCH
|
||||||
|
|
@ -427,6 +435,7 @@ ldrbs
|
||||||
LDRBS
|
LDRBS
|
||||||
LDRNE
|
LDRNE
|
||||||
ldsr
|
ldsr
|
||||||
|
ldxr
|
||||||
lidt
|
lidt
|
||||||
LINKR
|
LINKR
|
||||||
LJMP
|
LJMP
|
||||||
|
|
@ -502,6 +511,7 @@ movs
|
||||||
movw
|
movw
|
||||||
MOVWF
|
MOVWF
|
||||||
movx
|
movx
|
||||||
|
MPIDR
|
||||||
MPLAB
|
MPLAB
|
||||||
MPUCTRL
|
MPUCTRL
|
||||||
MQTT
|
MQTT
|
||||||
|
|
@ -646,6 +656,8 @@ PPUDR
|
||||||
PPUER
|
PPUER
|
||||||
PPUSR
|
PPUSR
|
||||||
ppux
|
ppux
|
||||||
|
Prbar
|
||||||
|
PRBAR
|
||||||
PRCR
|
PRCR
|
||||||
PREA
|
PREA
|
||||||
PREB
|
PREB
|
||||||
|
|
@ -653,11 +665,15 @@ PRIA
|
||||||
Prioritised
|
Prioritised
|
||||||
PRIS
|
PRIS
|
||||||
PRIVDEFENA
|
PRIVDEFENA
|
||||||
|
Prlar
|
||||||
|
PRLAR
|
||||||
PROCDLY
|
PROCDLY
|
||||||
PRODH
|
PRODH
|
||||||
PRODL
|
PRODL
|
||||||
PROGE
|
PROGE
|
||||||
Prokic
|
Prokic
|
||||||
|
Prselr
|
||||||
|
PRSELR
|
||||||
prtmacro
|
prtmacro
|
||||||
psha
|
psha
|
||||||
psplim
|
psplim
|
||||||
|
|
@ -700,6 +716,7 @@ REENT
|
||||||
REGA
|
REGA
|
||||||
RELD
|
RELD
|
||||||
Renesas
|
Renesas
|
||||||
|
restoreallgpregisters
|
||||||
reta
|
reta
|
||||||
reti
|
reti
|
||||||
RETP
|
RETP
|
||||||
|
|
@ -767,6 +784,8 @@ SCBR
|
||||||
SCDR
|
SCDR
|
||||||
SCER
|
SCER
|
||||||
SCSR
|
SCSR
|
||||||
|
Sctlr
|
||||||
|
SCTLR
|
||||||
SDCC
|
SDCC
|
||||||
SECU
|
SECU
|
||||||
SENDA
|
SENDA
|
||||||
|
|
@ -776,6 +795,7 @@ SETINTENA
|
||||||
SETPSW
|
SETPSW
|
||||||
SETR
|
SETR
|
||||||
setvect
|
setvect
|
||||||
|
sevl
|
||||||
SFRC
|
SFRC
|
||||||
SHLL
|
SHLL
|
||||||
SHLR
|
SHLR
|
||||||
|
|
@ -783,6 +803,7 @@ SHPR
|
||||||
SHTIM
|
SHTIM
|
||||||
SIFIVE
|
SIFIVE
|
||||||
sinclude
|
sinclude
|
||||||
|
slli
|
||||||
SODR
|
SODR
|
||||||
SOFTIRQ
|
SOFTIRQ
|
||||||
SPCK
|
SPCK
|
||||||
|
|
@ -805,6 +826,7 @@ STTBRK
|
||||||
STTDLY
|
STTDLY
|
||||||
STTOUT
|
STTOUT
|
||||||
STTTO
|
STTTO
|
||||||
|
stxr
|
||||||
SVACC
|
SVACC
|
||||||
svcne
|
svcne
|
||||||
SVDIS
|
SVDIS
|
||||||
|
|
@ -921,6 +943,7 @@ UNSUB
|
||||||
UNSUBACK
|
UNSUBACK
|
||||||
unsubscriptions
|
unsubscriptions
|
||||||
unsuspended
|
unsuspended
|
||||||
|
unupdated
|
||||||
UPAC
|
UPAC
|
||||||
URAD
|
URAD
|
||||||
URAT
|
URAT
|
||||||
|
|
@ -934,6 +957,7 @@ USRIO
|
||||||
utest
|
utest
|
||||||
utilises
|
utilises
|
||||||
utilising
|
utilising
|
||||||
|
vcsr
|
||||||
VDDCORE
|
VDDCORE
|
||||||
vect
|
vect
|
||||||
Vect
|
Vect
|
||||||
|
|
@ -944,6 +968,7 @@ visualisation
|
||||||
vldmdbeq
|
vldmdbeq
|
||||||
vldmia
|
vldmia
|
||||||
vldmiaeq
|
vldmiaeq
|
||||||
|
vlenb
|
||||||
VMSRNE
|
VMSRNE
|
||||||
vpop
|
vpop
|
||||||
VPOPNE
|
VPOPNE
|
||||||
|
|
@ -951,6 +976,7 @@ vpush
|
||||||
VPUSHNE
|
VPUSHNE
|
||||||
VRPM
|
VRPM
|
||||||
Vrtc
|
Vrtc
|
||||||
|
vsetvl
|
||||||
vstmdbeq
|
vstmdbeq
|
||||||
vstmiaeq
|
vstmiaeq
|
||||||
VTOR
|
VTOR
|
||||||
|
|
|
||||||
2
.github/allowed_urls.txt
vendored
2
.github/allowed_urls.txt
vendored
|
|
@ -1,3 +1,5 @@
|
||||||
https://www.renesas.com/us/en/document/mah/rh850f1k-group-users-manual-hardware?r=1170166
|
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/products/microcontrollers-microprocessors/rh850-automotive-mcus
|
||||||
https://www.renesas.com/us/en/software-tool/c-compiler-package-rh850-family#downloads
|
https://www.renesas.com/us/en/software-tool/c-compiler-package-rh850-family#downloads
|
||||||
|
https://www.microchip.com
|
||||||
|
https://www.microchip.com/support
|
||||||
|
|
|
||||||
20
.github/scripts/kernel_checker.py
vendored
20
.github/scripts/kernel_checker.py
vendored
|
|
@ -112,8 +112,17 @@ KERNEL_ARM_COLLAB_FILES_PATTERNS = [
|
||||||
r'.*portable/.*/ARM_CM23*',
|
r'.*portable/.*/ARM_CM23*',
|
||||||
r'.*portable/.*/ARM_CM33*',
|
r'.*portable/.*/ARM_CM33*',
|
||||||
r'.*portable/.*/ARM_CM35*',
|
r'.*portable/.*/ARM_CM35*',
|
||||||
|
r'.*portable/.*/ARM_CM52*',
|
||||||
r'.*portable/.*/ARM_CM55*',
|
r'.*portable/.*/ARM_CM55*',
|
||||||
r'.*portable/.*/ARM_CM85*',
|
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*',
|
||||||
|
r'.*portable/.*/ARM_STAR_MC3*',
|
||||||
|
r'.*include/task\.h$',
|
||||||
|
r'.*tasks\.c$',
|
||||||
]
|
]
|
||||||
|
|
||||||
KERNEL_HEADER = [
|
KERNEL_HEADER = [
|
||||||
|
|
@ -150,8 +159,9 @@ KERNEL_HEADER = [
|
||||||
FREERTOS_COPYRIGHT_REGEX = r"^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$"
|
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\.( \*\/)?$)|" + \
|
FREERTOS_ARM_COLLAB_COPYRIGHT_REGEX = r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$)|" + \
|
||||||
r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright 20\d\d Arm Limited and/or its affiliates( \*\/)?$)|" + \
|
r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright 20\d\d(-20\d\d)? Arm Limited and/or its affiliates( +<open-source-office@arm\.com>)?( \*\/)?$)|" + \
|
||||||
r"(^(;|#)?( *(\/\*|\*|#|\/\/))? <open-source-office@arm.com>( \*\/)?$)"
|
r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(c\) 20\d\d(-20\d\d)? Arm Technology \(China\) Co., Ltd.All Rights Reserved\.( \*\/)?$)|" + \
|
||||||
|
r"(^(;|#)?( *(\/\*|\*|#|\/\/))? <open-source-office@arm\.com>( \*\/)?$)"
|
||||||
|
|
||||||
|
|
||||||
class KernelHeaderChecker(HeaderChecker):
|
class KernelHeaderChecker(HeaderChecker):
|
||||||
|
|
@ -193,6 +203,8 @@ class KernelHeaderChecker(HeaderChecker):
|
||||||
]
|
]
|
||||||
if (len(lines) > 0) and (lines[0].find("#!") == 0):
|
if (len(lines) > 0) and (lines[0].find("#!") == 0):
|
||||||
lines.remove(lines[0])
|
lines.remove(lines[0])
|
||||||
|
if (len(lines) > 0) and (len(lines[-1].strip()) == 0):
|
||||||
|
lines.remove(lines[-1])
|
||||||
|
|
||||||
# Split lines in sections.
|
# Split lines in sections.
|
||||||
headers = dict()
|
headers = dict()
|
||||||
|
|
@ -210,7 +222,9 @@ class KernelHeaderChecker(HeaderChecker):
|
||||||
text_equal = self.isValidHeaderSection(file_ext, "text", headers["text"])
|
text_equal = self.isValidHeaderSection(file_ext, "text", headers["text"])
|
||||||
spdx_equal = self.isValidHeaderSection(file_ext, "spdx", headers["spdx"])
|
spdx_equal = self.isValidHeaderSection(file_ext, "spdx", headers["spdx"])
|
||||||
|
|
||||||
if text_equal and spdx_equal and len(headers["copyright"]) == 3:
|
if text_equal and spdx_equal:
|
||||||
|
# Some files do not have "open-source-office@arm.com" line.
|
||||||
|
if len(headers["copyright"]) == 3 or len(headers["copyright"]) == 2:
|
||||||
isValid = True
|
isValid = True
|
||||||
|
|
||||||
return isValid
|
return isValid
|
||||||
|
|
|
||||||
10
.github/workflows/auto-release.yml
vendored
10
.github/workflows/auto-release.yml
vendored
|
|
@ -18,6 +18,8 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-packager:
|
release-packager:
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
name: Release Packager
|
name: Release Packager
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -117,6 +119,14 @@ jobs:
|
||||||
./tools/.github/scripts/release.py "$REPO_OWNER" --kernel-repo-path=local_kernel --kernel-commit="$COMMIT_SHA_2" --new-kernel-version="$VERSION_NUMBER" --new-kernel-main-br-version="$MAIN_BR_VERSION_NUMBER"
|
./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 $?
|
exit $?
|
||||||
|
|
||||||
|
- name: Backup Release Asset
|
||||||
|
uses: FreeRTOS/CI-CD-Github-Actions/artifact-backup@main
|
||||||
|
with:
|
||||||
|
# This is dependent on the release script putting this zip file
|
||||||
|
# in this exact location.
|
||||||
|
artifact_path: ./FreeRTOS-KernelV${{ github.event.inputs.version_number }}.zip
|
||||||
|
release_tag: ${{ github.event.inputs.version_number }}
|
||||||
|
|
||||||
- name: Cleanup
|
- name: Cleanup
|
||||||
env:
|
env:
|
||||||
VERSION_NUMBER: ${{ github.event.inputs.version_number }}
|
VERSION_NUMBER: ${{ github.event.inputs.version_number }}
|
||||||
|
|
|
||||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -7,7 +7,7 @@ on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
formatting:
|
formatting:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.1
|
- uses: actions/checkout@v4.1.1
|
||||||
- name: Check Formatting of FreeRTOS-Kernel Files
|
- name: Check Formatting of FreeRTOS-Kernel Files
|
||||||
|
|
|
||||||
15
.github/workflows/coverity_scan.yml
vendored
15
.github/workflows/coverity_scan.yml
vendored
|
|
@ -42,11 +42,22 @@ jobs:
|
||||||
# ${{ env.stepName }}
|
# ${{ env.stepName }}
|
||||||
echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}"
|
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
|
wget -nv -q -O "$HOME/cov-analysis.tar.gz" https://scan.coverity.com/download/linux64 --post-data="token=${COVERITY_TOKEN}&project=FreeRTOS-Kernel"
|
||||||
echo "cov_scan_path=$(pwd)/cov_scan/bin" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
|
EXPECTED_MD5="e4418004b073140d67390cffba79c3b2"
|
||||||
|
GENERATED_MD5=$(md5sum "$HOME/cov-analysis.tar.gz" | awk '{print $1}')
|
||||||
|
|
||||||
|
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 "::endgroup::"
|
||||||
echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} "
|
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:
|
- env:
|
||||||
stepName: Coverity Build
|
stepName: Coverity Build
|
||||||
|
|
|
||||||
25
.github/workflows/formatting.yml
vendored
25
.github/workflows/formatting.yml
vendored
|
|
@ -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
|
|
||||||
2
.github/workflows/kernel-checks.yml
vendored
2
.github/workflows/kernel-checks.yml
vendored
|
|
@ -5,7 +5,7 @@ on: [push, pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
kernel-checker:
|
kernel-checker:
|
||||||
name: FreeRTOS Kernel Header Checks
|
name: FreeRTOS Kernel Header Checks
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
# Install python 3
|
# Install python 3
|
||||||
- name: Tool Setup
|
- name: Tool Setup
|
||||||
|
|
|
||||||
41
.github/workflows/kernel-demos.yml
vendored
41
.github/workflows/kernel-demos.yml
vendored
|
|
@ -156,14 +156,27 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
# ${{ env.stepName }}
|
# ${{ env.stepName }}
|
||||||
echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}"
|
echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}"
|
||||||
curl -L -O https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-LlCjWuAbzH/9.3.1.2/msp430-gcc-full-linux-x64-installer-9.3.1.2.7z
|
|
||||||
sudo apt update -y
|
sudo apt update -y
|
||||||
sudo apt install -y p7zip-full
|
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
|
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
|
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
|
sudo ./msp430-gcc-full-linux-x64-installer-9.3.1.2.run --prefix /usr/bin/msp430-gcc --mode unattended
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
popd
|
||||||
echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}"
|
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
|
- name: Build msp430_GCC Demo
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
@ -211,21 +224,23 @@ jobs:
|
||||||
sudo apt install -y autogen gawk libgmp-dev libmpc-dev libmpfr-dev
|
sudo apt install -y autogen gawk libgmp-dev libmpc-dev libmpfr-dev
|
||||||
sudo apt install -y patchutils sharutils zlib1g-dev autoconf2.64
|
sudo apt install -y patchutils sharutils zlib1g-dev autoconf2.64
|
||||||
|
|
||||||
|
pushd $HOME
|
||||||
# Download the mb-gcc toolchain from github
|
# Download the mb-gcc toolchain from github
|
||||||
curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/binutils-microblaze_2.35-2021-0623+1_amd64.deb;
|
curl -L -o 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 https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/gcc-microblaze_10.2.0-2021-0623+2_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 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-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 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-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 https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze_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 https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/newlib-source_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
|
# Install the packages for the toolchain
|
||||||
sudo apt install -y ./binutils-microblaze*.deb;
|
sudo apt install -y $HOME/binutils-microblaze.deb;
|
||||||
sudo apt install -y ./gcc-microblaze*.deb;
|
sudo apt install -y $HOME/gcc-microblaze.deb;
|
||||||
sudo apt install -y ./libnewlib-microblaze-dev*.deb;
|
sudo apt install -y $HOME/libnewlib-microblaze-dev.deb;
|
||||||
sudo apt install -y ./libnewlib-microblaze-doc*.deb;
|
sudo apt install -y $HOME/libnewlib-microblaze-doc.deb;
|
||||||
sudo apt install -y ./libnewlib-microblaze*.deb;
|
sudo apt install -y $HOME/libnewlib-microblaze.deb;
|
||||||
sudo apt install -y ./newlib-source*.deb;
|
sudo apt install -y $HOME/newlib-source.deb;
|
||||||
|
|
||||||
# Validate that the toolchain is in the path and can be called
|
# Validate that the toolchain is in the path and can be called
|
||||||
which mb-gcc
|
which mb-gcc
|
||||||
|
|
|
||||||
2
.github/workflows/unit-tests.yml
vendored
2
.github/workflows/unit-tests.yml
vendored
|
|
@ -3,7 +3,7 @@ on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run:
|
run:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Parent Repository
|
- name: Checkout Parent Repository
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,10 @@ if(NOT FREERTOS_PORT)
|
||||||
" GCC_ARM_CM35P_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-secure\n"
|
" GCC_ARM_CM35P_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-secure\n"
|
||||||
" GCC_ARM_CM35P_SECURE - Compiler: GCC Target: ARM Cortex-M35P secure\n"
|
" GCC_ARM_CM35P_SECURE - Compiler: GCC Target: ARM Cortex-M35P secure\n"
|
||||||
" GCC_ARM_CM35P_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-trustzone non-secure\n"
|
" GCC_ARM_CM35P_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-trustzone non-secure\n"
|
||||||
|
" GCC_ARM_CM52_NONSECURE - Compiler: GCC Target: ARM Cortex-M52 non-secure\n"
|
||||||
|
" GCC_ARM_CM52_SECURE - Compiler: GCC Target: ARM Cortex-M52 secure\n"
|
||||||
|
" GCC_ARM_CM52_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M52 non-trustzone non-secure\n"
|
||||||
|
" GCC_ARM_CM52_TFM - Compiler: GCC Target: ARM Cortex-M52 non-secure for TF-M\n"
|
||||||
" GCC_ARM_CM55_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-secure\n"
|
" GCC_ARM_CM55_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-secure\n"
|
||||||
" GCC_ARM_CM55_SECURE - Compiler: GCC Target: ARM Cortex-M55 secure\n"
|
" GCC_ARM_CM55_SECURE - Compiler: GCC Target: ARM Cortex-M55 secure\n"
|
||||||
" GCC_ARM_CM55_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-trustzone non-secure\n"
|
" GCC_ARM_CM55_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-trustzone non-secure\n"
|
||||||
|
|
@ -84,9 +88,14 @@ if(NOT FREERTOS_PORT)
|
||||||
" GCC_ARM_CM85_SECURE - Compiler: GCC Target: ARM Cortex-M85 secure\n"
|
" GCC_ARM_CM85_SECURE - Compiler: GCC Target: ARM Cortex-M85 secure\n"
|
||||||
" GCC_ARM_CM85_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M85 non-trustzone non-secure\n"
|
" 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_CM85_TFM - Compiler: GCC Target: ARM Cortex-M85 non-secure for TF-M\n"
|
||||||
|
" GCC_ARM_STAR_MC3_NONSECURE - Compiler: GCC Target: Arm China STAR-MC3 non-secure\n"
|
||||||
|
" GCC_ARM_STAR_MC3_SECURE - Compiler: GCC Target: Arm China STAR-MC3 secure\n"
|
||||||
|
" GCC_ARM_STAR_MC3_NTZ_NONSECURE - Compiler: GCC Target: Arm China STAR-MC3 non-trustzone non-secure\n"
|
||||||
|
" GCC_ARM_STAR_MC3_TFM - Compiler: GCC Target: Arm China STAR-MC3 non-secure for TF-M\n"
|
||||||
" GCC_ARM_CR5 - Compiler: GCC Target: ARM Cortex-R5\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_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_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_AT91FR40008 - Compiler: GCC Target: ARM7 Atmel AT91R40008\n"
|
||||||
" GCC_ARM7_AT91SAM7S - Compiler: GCC Target: ARM7 Atmel AT91SAM7S\n"
|
" GCC_ARM7_AT91SAM7S - Compiler: GCC Target: ARM7 Atmel AT91SAM7S\n"
|
||||||
" GCC_ARM7_LPC2000 - Compiler: GCC Target: ARM7 LPC2000\n"
|
" GCC_ARM7_LPC2000 - Compiler: GCC Target: ARM7 LPC2000\n"
|
||||||
|
|
@ -142,6 +151,10 @@ if(NOT FREERTOS_PORT)
|
||||||
" IAR_ARM_CM35P_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-secure\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_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_CM35P_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-trustzone non-secure\n"
|
||||||
|
" IAR_ARM_CM52_NONSECURE - Compiler: IAR Target: ARM Cortex-M52 non-secure\n"
|
||||||
|
" IAR_ARM_CM52_SECURE - Compiler: IAR Target: ARM Cortex-M52 secure\n"
|
||||||
|
" IAR_ARM_CM52_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M52 non-trustzone non-secure\n"
|
||||||
|
" IAR_ARM_CM52_TFM - Compiler: IAR Target: ARM Cortex-M52 non-secure for TF-M\n"
|
||||||
" IAR_ARM_CM55_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 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_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_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n"
|
||||||
|
|
@ -150,6 +163,10 @@ if(NOT FREERTOS_PORT)
|
||||||
" IAR_ARM_CM85_SECURE - Compiler: IAR Target: ARM Cortex-M85 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_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_CM85_TFM - Compiler: IAR Target: ARM Cortex-M85 non-secure for TF-M\n"
|
||||||
|
" IAR_ARM_STAR_MC3_NONSECURE - Compiler: IAR Target: Arm China STAR-MC3 non-secure\n"
|
||||||
|
" IAR_ARM_STAR_MC3_SECURE - Compiler: IAR Target: Arm China STAR-MC3 secure\n"
|
||||||
|
" IAR_ARM_STAR_MC3_NTZ_NONSECURE - Compiler: IAR Target: Arm China STAR-MC3 non-trustzone non-secure\n"
|
||||||
|
" IAR_ARM_STAR_MC3_TFM - Compiler: IAR Target: Arm China STAR-MC3 non-secure for TF-M\n"
|
||||||
" IAR_ARM_CRX_NOGIC - Compiler: IAR Target: ARM Cortex-Rx no GIC\n"
|
" IAR_ARM_CRX_NOGIC - Compiler: IAR Target: ARM Cortex-Rx no GIC\n"
|
||||||
" IAR_ATMEGA323 - Compiler: IAR Target: ATMega323\n"
|
" IAR_ATMEGA323 - Compiler: IAR Target: ATMega323\n"
|
||||||
" IAR_ATMEL_SAM7S64 - Compiler: IAR Target: Atmel SAM7S64\n"
|
" IAR_ATMEL_SAM7S64 - Compiler: IAR Target: Atmel SAM7S64\n"
|
||||||
|
|
|
||||||
88
MISRA.md
88
MISRA.md
|
|
@ -19,6 +19,7 @@ grep 'MISRA Ref 8.4.1' . -rI
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Dir 4.7
|
#### Dir 4.7
|
||||||
|
|
||||||
MISRA C:2012 Dir 4.7: If a function returns error information, then that error
|
MISRA C:2012 Dir 4.7: If a function returns error information, then that error
|
||||||
information shall be tested.
|
information shall be tested.
|
||||||
|
|
||||||
|
|
@ -143,3 +144,90 @@ _Ref 21.6.1_
|
||||||
- The Standard Library function snprintf is used in vTaskListTasks and
|
- The Standard Library function snprintf is used in vTaskListTasks and
|
||||||
vTaskGetRunTimeStatistics APIs, both of which are utility functions only and
|
vTaskGetRunTimeStatistics APIs, both of which are utility functions only and
|
||||||
are not considered part of core kernel implementation.
|
are not considered part of core kernel implementation.
|
||||||
|
|
||||||
|
### Unsuppressed Deviations
|
||||||
|
|
||||||
|
Certain deviating code is left unsuppressed for awareness. These violations
|
||||||
|
will be reported when audited by a MISRA-checking static analysis tool.
|
||||||
|
|
||||||
|
Some of these unsuppressed exceptions correspond to example code provided
|
||||||
|
either for demonstration or verification of the FreeRTOS kernel. This code
|
||||||
|
is not considered part of the kernel implementation and should not be used
|
||||||
|
in an application.
|
||||||
|
|
||||||
|
Other unsuppressed violations are left present in the kernel implementation
|
||||||
|
as implementations, code, or other missing functionality being flagged for
|
||||||
|
violations will be present with the porting layer provided by the
|
||||||
|
application. The presence of these errors after providing a port indicates
|
||||||
|
a valid MISRA issue.
|
||||||
|
|
||||||
|
#### Rule 2.1
|
||||||
|
|
||||||
|
MISRA C:2012 Dir 2.1: A project shall not contain unreachable code
|
||||||
|
|
||||||
|
_Ref 2.1_
|
||||||
|
- Simplified example contains unreachable code for demonstration of
|
||||||
|
FreeRTOS scheduler. A production implementation should not contain
|
||||||
|
this.
|
||||||
|
|
||||||
|
Affected Files:
|
||||||
|
- examples/cmake_example/main.c
|
||||||
|
|
||||||
|
#### Rule 2.2
|
||||||
|
|
||||||
|
MISRA C:2012 Dir 2.2: There shall be no dead code.
|
||||||
|
|
||||||
|
_Ref 2.2_
|
||||||
|
- `vPortEndScheduler` is erroneously determined to be dead code due to
|
||||||
|
the use of a simplified verification port.
|
||||||
|
|
||||||
|
Affected Files:
|
||||||
|
- tasks.c
|
||||||
|
|
||||||
|
#### Dir 4.12
|
||||||
|
|
||||||
|
MISRA C:2012 Dir 4.12: Dynamic allocation shall not be used
|
||||||
|
|
||||||
|
_Ref 4.12_
|
||||||
|
- Heap memory solutions utilize pvPortMalloc/vPortFree to provide heap
|
||||||
|
memory for dynamic object allocation. These functions may rely upon
|
||||||
|
the malloc/free of the underlying port. Static allocation is recommended
|
||||||
|
for MISRA compliant applications.
|
||||||
|
|
||||||
|
Affected Files:
|
||||||
|
- portable/MemMang/heap_*.c
|
||||||
|
|
||||||
|
|
||||||
|
#### Rule 8.6
|
||||||
|
|
||||||
|
MISRA C:2012 Rule 8.6: An identifier with external linkage shall have exactly
|
||||||
|
one external definition.
|
||||||
|
|
||||||
|
_Ref 8.6.1_
|
||||||
|
- Port layer function declarations are provided without corresponding
|
||||||
|
implementations to provide for ease of porting to a device. These definitions
|
||||||
|
cannot be implemented until a port is selected.
|
||||||
|
|
||||||
|
#### Rule 21.3
|
||||||
|
|
||||||
|
MISRA C-2012 Rule 21.3: The memory allocation and deallocation functions of
|
||||||
|
<stdlib.h> shall not be used.
|
||||||
|
|
||||||
|
_Ref 21.3_
|
||||||
|
- See justification from Directive 4.12
|
||||||
|
|
||||||
|
Affected Files:
|
||||||
|
- portable/MemMang/heap_*.c
|
||||||
|
|
||||||
|
#### Rule 21.6
|
||||||
|
|
||||||
|
MISRA C-2012 Rule 21.6: The Standard Library input/output functions shall not
|
||||||
|
be used.
|
||||||
|
|
||||||
|
_Ref 21.6.1_
|
||||||
|
- The Standard Library function `printf` is used in examples to provide a
|
||||||
|
simple getting started demonstration. This example is not considered part
|
||||||
|
of the kernel implementation.
|
||||||
|
|
||||||
|
Affected Files:
|
||||||
|
- examples/cmake_example/main.c
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml?query=branch%3Amain+event%3Apush+workflow%3A%22CMock+Unit+Tests%22++)
|
[](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml?query=branch%3Amain+event%3Apush+workflow%3A%22CMock+Unit+Tests%22++)
|
||||||
[](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel)
|
[](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel)
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
||||||
* pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
|
* pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
|
||||||
* are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
|
* are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
|
||||||
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
* wait condition is met if any of the bits set in uxBitsToWaitFor are also set
|
||||||
* in uxCurrentEventBits.
|
* in uxCurrentEventBits.
|
||||||
*/
|
*/
|
||||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||||
|
|
@ -501,7 +501,7 @@
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToClear )
|
const EventBits_t uxBitsToClear )
|
||||||
|
|
@ -511,14 +511,14 @@
|
||||||
traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear );
|
traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
xReturn = xTimerPendFunctionCallFromISR( &vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
||||||
|
|
||||||
traceRETURN_xEventGroupClearBitsFromISR( xReturn );
|
traceRETURN_xEventGroupClearBitsFromISR( xReturn );
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||||
|
|
@ -812,7 +812,7 @@
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToSet,
|
const EventBits_t uxBitsToSet,
|
||||||
|
|
@ -823,14 +823,14 @@
|
||||||
traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken );
|
traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
xReturn = xTimerPendFunctionCallFromISR( &vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
traceRETURN_xEventGroupSetBitsFromISR( xReturn );
|
traceRETURN_xEventGroupSetBitsFromISR( xReturn );
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ int main( void )
|
||||||
|
|
||||||
( void ) printf( "Example FreeRTOS Project\n" );
|
( void ) printf( "Example FreeRTOS Project\n" );
|
||||||
|
|
||||||
( void ) xTaskCreateStatic( exampleTask,
|
( void ) xTaskCreateStatic( &exampleTask,
|
||||||
"example",
|
"example",
|
||||||
configMINIMAL_STACK_SIZE,
|
configMINIMAL_STACK_SIZE,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
||||||
|
|
@ -415,6 +415,8 @@
|
||||||
* number of the failing assert (for example, "vAssertCalled( __FILE__, __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
|
* )" or it can simple disable interrupts and sit in a loop to halt all
|
||||||
* execution on the failing line for viewing in a debugger. */
|
* execution on the failing line for viewing in a debugger. */
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#define configASSERT( x ) \
|
#define configASSERT( x ) \
|
||||||
if( ( x ) == 0 ) \
|
if( ( x ) == 0 ) \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -422,6 +424,7 @@
|
||||||
for( ; ; ) \
|
for( ; ; ) \
|
||||||
; \
|
; \
|
||||||
}
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* FreeRTOS MPU specific definitions. *****************************************/
|
/* FreeRTOS MPU specific definitions. *****************************************/
|
||||||
|
|
@ -599,10 +602,10 @@
|
||||||
|
|
||||||
/* Set configENABLE_MVE to 1 to enable the M-Profile Vector Extension (MVE)
|
/* 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
|
* 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
|
* applicable to Cortex-M52, Cortex-M55, Cortex-M85 and STAR-MC3 ports as
|
||||||
* (MVE) is available only on these architectures. configENABLE_MVE must be left
|
* M-Profile Vector Extension (MVE) is available only on these architectures.
|
||||||
* undefined, or defined to 0 for the Cortex-M23,Cortex-M33 and Cortex-M35P
|
* configENABLE_MVE must be left undefined, or defined to 0 for the
|
||||||
* ports. */
|
* Cortex-M23,Cortex-M33 and Cortex-M35P ports. */
|
||||||
#define configENABLE_MVE 1
|
#define configENABLE_MVE 1
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
@ -650,7 +653,7 @@
|
||||||
#define INCLUDE_uxTaskPriorityGet 1
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
#define INCLUDE_vTaskDelete 1
|
#define INCLUDE_vTaskDelete 1
|
||||||
#define INCLUDE_vTaskSuspend 1
|
#define INCLUDE_vTaskSuspend 1
|
||||||
#define INCLUDE_vTaskDelayUntil 1
|
#define INCLUDE_xTaskDelayUntil 1
|
||||||
#define INCLUDE_vTaskDelay 1
|
#define INCLUDE_vTaskDelay 1
|
||||||
#define INCLUDE_xTaskGetSchedulerState 1
|
#define INCLUDE_xTaskGetSchedulerState 1
|
||||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,16 @@
|
||||||
#define configASSERT_DEFINED 1
|
#define configASSERT_DEFINED 1
|
||||||
#endif
|
#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. */
|
/* Basic FreeRTOS definitions. */
|
||||||
#include "projdefs.h"
|
#include "projdefs.h"
|
||||||
|
|
||||||
|
|
@ -3040,16 +3050,6 @@
|
||||||
#define configCONTROL_INFINITE_LOOP()
|
#define configCONTROL_INFINITE_LOOP()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set configENABLE_PAC and/or configENABLE_BTI to 1 to enable PAC and/or BTI
|
|
||||||
* support and 0 to disable them. These are currently used in ARMv8.1-M ports. */
|
|
||||||
#ifndef configENABLE_PAC
|
|
||||||
#define configENABLE_PAC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef configENABLE_BTI
|
|
||||||
#define configENABLE_BTI 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
|
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
|
||||||
* dynamically allocated RAM, in which case when any task is deleted it is known
|
* dynamically allocated RAM, in which case when any task is deleted it is known
|
||||||
* that both the task's stack and TCB need to be freed. Sometimes the
|
* that both the task's stack and TCB need to be freed. Sometimes the
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,10 @@ void vCoRoutineSchedule( void );
|
||||||
* \defgroup crSTART crSTART
|
* \defgroup crSTART crSTART
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#define crEND() }
|
#define crEND() }
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These macros are intended for internal use by the co-routine implementation
|
* These macros are intended for internal use by the co-routine implementation
|
||||||
|
|
|
||||||
|
|
@ -452,13 +452,10 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||||
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
#else
|
#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \
|
|
||||||
xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
|
|
@ -607,14 +604,11 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToSet,
|
const EventBits_t uxBitsToSet,
|
||||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
#else
|
#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \
|
|
||||||
xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
*
|
*
|
||||||
* In addition to it's value, each list item contains a pointer to the next
|
* 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)
|
* 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
|
* pointers are included for efficiency of list manipulation. There is
|
||||||
* effectively a two way link between the object containing the list item and
|
* effectively a two way link between the object containing the list item and
|
||||||
* the list item itself.
|
* the list item itself.
|
||||||
|
|
|
||||||
|
|
@ -409,13 +409,16 @@ EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
|
|
||||||
BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
|
BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
|
||||||
StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
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;
|
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. */
|
/* MPU versions of message/stream_buffer.h API functions. */
|
||||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
const void * pvTxData,
|
const void * pvTxData,
|
||||||
|
|
|
||||||
|
|
@ -202,8 +202,8 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t;
|
||||||
* char ucData[ 20 ];
|
* char ucData[ 20 ];
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
#define QUEUE_LENGTH 10
|
* #define QUEUE_LENGTH 10
|
||||||
#define ITEM_SIZE sizeof( uint32_t )
|
* #define ITEM_SIZE sizeof( uint32_t )
|
||||||
*
|
*
|
||||||
* // xQueueBuffer will hold the queue structure.
|
* // xQueueBuffer will hold the queue structure.
|
||||||
* StaticQueue_t xQueueBuffer;
|
* StaticQueue_t xQueueBuffer;
|
||||||
|
|
@ -217,8 +217,8 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t;
|
||||||
* QueueHandle_t xQueue1;
|
* QueueHandle_t xQueue1;
|
||||||
*
|
*
|
||||||
* // Create a queue capable of containing 10 uint32_t values.
|
* // Create a queue capable of containing 10 uint32_t values.
|
||||||
* xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
|
* xQueue1 = xQueueCreateStatic( QUEUE_LENGTH, // The number of items the queue can hold.
|
||||||
* ITEM_SIZE // The size of each item in the queue
|
* ITEM_SIZE, // The size of each item in the queue.
|
||||||
* &( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
|
* &( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
|
||||||
* &xQueueBuffer ); // The buffer that will hold the queue structure.
|
* &xQueueBuffer ); // The buffer that will hold the queue structure.
|
||||||
*
|
*
|
||||||
|
|
@ -1026,7 +1026,11 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||||
* // Now the buffer is empty we can switch context if necessary.
|
* // Now the buffer is empty we can switch context if necessary.
|
||||||
* if( xHigherPriorityTaskWoken )
|
* if( xHigherPriorityTaskWoken )
|
||||||
* {
|
* {
|
||||||
* taskYIELD ();
|
* // As xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||||
|
* // switch should be requested. The macro used is port specific and
|
||||||
|
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||||
|
* // refer to the documentation page for the port being used.
|
||||||
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
|
|
@ -1098,7 +1102,11 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||||
* // Now the buffer is empty we can switch context if necessary.
|
* // Now the buffer is empty we can switch context if necessary.
|
||||||
* if( xHigherPriorityTaskWoken )
|
* if( xHigherPriorityTaskWoken )
|
||||||
* {
|
* {
|
||||||
* taskYIELD ();
|
* // As xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||||
|
* // switch should be requested. The macro used is port specific and
|
||||||
|
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||||
|
* // refer to the documentation page for the port being used.
|
||||||
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
|
|
@ -1429,23 +1437,27 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue,
|
||||||
* // ISR that outputs all the characters received on the queue.
|
* // ISR that outputs all the characters received on the queue.
|
||||||
* void vISR_Routine( void )
|
* void vISR_Routine( void )
|
||||||
* {
|
* {
|
||||||
* BaseType_t xTaskWokenByReceive = pdFALSE;
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
* char cRxedChar;
|
* char cRxedChar;
|
||||||
*
|
*
|
||||||
* while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
|
* while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xHigherPriorityTaskWoken) )
|
||||||
* {
|
* {
|
||||||
* // A character was received. Output the character now.
|
* // A character was received. Output the character now.
|
||||||
* vOutputCharacter( cRxedChar );
|
* vOutputCharacter( cRxedChar );
|
||||||
*
|
*
|
||||||
* // If removing the character from the queue woke the task that was
|
* // If removing the character from the queue woke the task that was
|
||||||
* // posting onto the queue xTaskWokenByReceive will have been set to
|
* // posting onto the queue xHigherPriorityTaskWoken will have been set to
|
||||||
* // pdTRUE. No matter how many times this loop iterates only one
|
* // pdTRUE. No matter how many times this loop iterates only one
|
||||||
* // task will be woken.
|
* // task will be woken.
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* if( xTaskWokenByReceive != ( char ) pdFALSE;
|
* if( xHigherPrioritytaskWoken == pdTRUE );
|
||||||
* {
|
* {
|
||||||
* taskYIELD ();
|
* // As xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||||
|
* // switch should be requested. The macro used is port specific and
|
||||||
|
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||||
|
* // refer to the documentation page for the port being used.
|
||||||
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@
|
||||||
|
|
||||||
typedef QueueHandle_t SemaphoreHandle_t;
|
typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
|
|
||||||
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U )
|
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( UBaseType_t ) 1U )
|
||||||
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
|
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0U )
|
||||||
#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U )
|
#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U )
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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 <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -68,6 +69,9 @@
|
||||||
#if defined( portARMV8M_MINOR_VERSION ) && ( portARMV8M_MINOR_VERSION >= 1 )
|
#if defined( portARMV8M_MINOR_VERSION ) && ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
#define tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ( 1U << 5U )
|
#define tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ( 1U << 5U )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
#define tskMPU_REGION_NON_SHAREABLE ( 1U << 6U )
|
||||||
|
#define tskMPU_REGION_OUTER_SHAREABLE ( 1U << 7U )
|
||||||
|
#define tskMPU_REGION_INNER_SHAREABLE ( 1U << 8U )
|
||||||
|
|
||||||
/* MPU region permissions stored in MPU settings to
|
/* MPU region permissions stored in MPU settings to
|
||||||
* authorize access requests. */
|
* authorize access requests. */
|
||||||
|
|
@ -602,12 +606,12 @@ typedef enum
|
||||||
* \defgroup xTaskCreateRestricted xTaskCreateRestricted
|
* \defgroup xTaskCreateRestricted xTaskCreateRestricted
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#if ( portUSING_MPU_WRAPPERS == 1 )
|
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||||
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
|
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
|
||||||
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
|
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||||
BaseType_t xTaskCreateRestrictedAffinitySet( const TaskParameters_t * const pxTaskDefinition,
|
BaseType_t xTaskCreateRestrictedAffinitySet( const TaskParameters_t * const pxTaskDefinition,
|
||||||
UBaseType_t uxCoreAffinityMask,
|
UBaseType_t uxCoreAffinityMask,
|
||||||
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
|
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -897,7 +901,8 @@ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION;
|
||||||
*
|
*
|
||||||
* @return Value which can be used to check whether the task was actually delayed.
|
* @return Value which can be used to check whether the task was actually delayed.
|
||||||
* Will be pdTRUE if the task way delayed and pdFALSE otherwise. A task will not
|
* Will be pdTRUE if the task way delayed and pdFALSE otherwise. A task will not
|
||||||
* be delayed if the next expected wake time is in the past.
|
* be delayed if the next expected wake time is in the past. This prevents periodic
|
||||||
|
* tasks from accumulating delays and allows them to resume their regular timing pattern.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
* @code{c}
|
* @code{c}
|
||||||
|
|
@ -2612,9 +2617,8 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION;
|
||||||
* notification value at that index being updated. ulValue is not used and
|
* notification value at that index being updated. ulValue is not used and
|
||||||
* xTaskNotifyIndexed() always returns pdPASS in this case.
|
* xTaskNotifyIndexed() always returns pdPASS in this case.
|
||||||
*
|
*
|
||||||
* pulPreviousNotificationValue -
|
* @param pulPreviousNotificationValue Can be used to pass out the subject
|
||||||
* Can be used to pass out the subject task's notification value before any
|
* task's notification value before any bits are modified by the notify function.
|
||||||
* bits are modified by the notify function.
|
|
||||||
*
|
*
|
||||||
* @return Dependent on the value of eAction. See the description of the
|
* @return Dependent on the value of eAction. See the description of the
|
||||||
* eAction parameter.
|
* eAction parameter.
|
||||||
|
|
@ -2759,6 +2763,9 @@ BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify,
|
||||||
* updated. ulValue is not used and xTaskNotify() always returns pdPASS in
|
* updated. ulValue is not used and xTaskNotify() always returns pdPASS in
|
||||||
* this case.
|
* this case.
|
||||||
*
|
*
|
||||||
|
* @param pulPreviousNotificationValue Can be used to pass out the subject
|
||||||
|
* task's notification value before any bits are modified by the notify function.
|
||||||
|
*
|
||||||
* @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set
|
* @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set
|
||||||
* *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
|
* *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
|
||||||
* task to which the notification was sent to leave the Blocked state, and the
|
* task to which the notification was sent to leave the Blocked state, and the
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
||||||
Armv8.1-M ports.
|
Armv8.1-M ports.
|
||||||
Do not use the files located here! These file are copied into separate
|
Do not use the files located here! These file are copied into separate
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to each
|
FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3]_NNN directories
|
||||||
FreeRTOS release.
|
prior to each FreeRTOS release.
|
||||||
|
|
||||||
If your Armv8-M and Armv8.1-M application uses TrustZone then use the files from the
|
If your Armv8-M and Armv8.1-M application uses TrustZone then use the files from the
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories.
|
FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3] directories.
|
||||||
|
|
||||||
If your Armv8-M and Armv8.1-M application does not use TrustZone then use the files from
|
If your Armv8-M and Armv8.1-M application does not use TrustZone then use the files from
|
||||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories.
|
the FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3]_NTZ directories.
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ _THIS_FILE_DIRECTORY_ = os.path.dirname(os.path.realpath(__file__))
|
||||||
_FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_)
|
_FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_)
|
||||||
|
|
||||||
_COMPILERS_ = ['GCC', 'IAR']
|
_COMPILERS_ = ['GCC', 'IAR']
|
||||||
_ARCH_NS_ = ['ARM_CM85', 'ARM_CM85_NTZ', 'ARM_CM55', 'ARM_CM55_NTZ', 'ARM_CM35P', 'ARM_CM35P_NTZ', 'ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
|
_ARCH_NS_ = ['ARM_CM85', 'ARM_CM85_NTZ', 'ARM_CM55', 'ARM_CM55_NTZ', 'ARM_CM52', 'ARM_CM52_NTZ', 'ARM_CM35P', 'ARM_CM35P_NTZ', 'ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ', 'ARM_STAR_MC3', 'ARM_STAR_MC3_NTZ']
|
||||||
_ARCH_S_ = ['ARM_CM85', 'ARM_CM55', 'ARM_CM35P', 'ARM_CM33', 'ARM_CM23']
|
_ARCH_S_ = ['ARM_CM85', 'ARM_CM55', 'ARM_CM52', 'ARM_CM35P', 'ARM_CM33', 'ARM_CM23', 'ARM_STAR_MC3']
|
||||||
|
|
||||||
# Files to be compiled in the Secure Project
|
# Files to be compiled in the Secure Project
|
||||||
_SECURE_COMMON_FILE_PATHS_ = [
|
_SECURE_COMMON_FILE_PATHS_ = [
|
||||||
|
|
@ -48,16 +48,20 @@ _SECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
'GCC':{
|
'GCC':{
|
||||||
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM23')],
|
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM23')],
|
||||||
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
'ARM_CM35P' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
|
'ARM_CM52' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')]
|
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
|
'ARM_STAR_MC3' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')]
|
||||||
},
|
},
|
||||||
'IAR':{
|
'IAR':{
|
||||||
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM23')],
|
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM23')],
|
||||||
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
'ARM_CM35P' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
|
'ARM_CM52' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')]
|
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
|
'ARM_STAR_MC3' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,6 +82,12 @@ _NONSECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')],
|
||||||
|
'ARM_CM52' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM52', 'portmacro.h')],
|
||||||
|
'ARM_CM52_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM52', 'portmacro.h')],
|
||||||
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'),
|
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'),
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')],
|
||||||
|
|
@ -89,7 +99,13 @@ _NONSECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')],
|
||||||
'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')]
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')],
|
||||||
|
'ARM_STAR_MC3' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_STAR_MC3', 'portmacro.h')],
|
||||||
|
'ARM_STAR_MC3_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_STAR_MC3', 'portmacro.h')]
|
||||||
},
|
},
|
||||||
'IAR':{
|
'IAR':{
|
||||||
'ARM_CM23' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM23')],
|
'ARM_CM23' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM23')],
|
||||||
|
|
@ -102,6 +118,12 @@ _NONSECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')],
|
||||||
|
'ARM_CM52' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM52', 'portmacro.h')],
|
||||||
|
'ARM_CM52_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM52', 'portmacro.h')],
|
||||||
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'),
|
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'),
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')],
|
||||||
|
|
@ -113,7 +135,13 @@ _NONSECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')],
|
||||||
'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')]
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')],
|
||||||
|
'ARM_STAR_MC3' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_STAR_MC3', 'portmacro.h')],
|
||||||
|
'ARM_STAR_MC3_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_STAR_MC3', 'portmacro.h')]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
||||||
Armv8.1-M ports.
|
Armv8.1-M ports.
|
||||||
Do not use the files located here! These file are copied into separate
|
Do not use the files located here! These file are copied into separate
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to
|
FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3]_NNN directories
|
||||||
each FreeRTOS release.
|
prior to each FreeRTOS release.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories.
|
FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3] directories.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
||||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories.
|
the FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3]_NTZ directories.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
80
portable/ARMv8M/non_secure/portable/GCC/ARM_CM52/portmacro.h
Normal file
80
portable/ARMv8M/non_secure/portable/GCC/ARM_CM52/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2026 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "STAR-MC3"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
87
portable/ARMv8M/non_secure/portable/IAR/ARM_CM52/portmacro.h
Normal file
87
portable/ARMv8M/non_secure/portable/IAR/ARM_CM52/portmacro.h
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __root
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
* the source code because to do so would cause other compilers to generate
|
||||||
|
* warnings. */
|
||||||
|
#pragma diag_suppress=Be006
|
||||||
|
#pragma diag_suppress=Pa082
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2026 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "STAR-MC3"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __root
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
* the source code because to do so would cause other compilers to generate
|
||||||
|
* warnings. */
|
||||||
|
#pragma diag_suppress=Be006
|
||||||
|
#pragma diag_suppress=Pa082
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
||||||
Armv8.1-M ports.
|
Armv8.1-M ports.
|
||||||
Do not use the files located here! These file are copied into separate
|
Do not use the files located here! These file are copied into separate
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to
|
FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3]_NNN directories
|
||||||
each FreeRTOS release.
|
prior to each FreeRTOS release.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories.
|
FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3] directories.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
||||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories.
|
the FreeRTOS/Source/portable/[compiler]/ARM_[CM23|CM33|CM52|CM55|CM85|STAR_MC3]_NTZ directories.
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,28 @@ add_library(freertos_kernel_port OBJECT
|
||||||
GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NONSECURE>:
|
||||||
|
GCC/ARM_CM52/non_secure/port.c
|
||||||
|
GCC/ARM_CM52/non_secure/portasm.c
|
||||||
|
GCC/ARM_CM52/non_secure/mpu_wrappers_v2_asm.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_SECURE>:
|
||||||
|
GCC/ARM_CM52/secure/secure_context_port.c
|
||||||
|
GCC/ARM_CM52/secure/secure_context.c
|
||||||
|
GCC/ARM_CM52/secure/secure_heap.c
|
||||||
|
GCC/ARM_CM52/secure/secure_init.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NTZ_NONSECURE>:
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/portasm.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_TFM>:
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/portasm.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||||
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:
|
||||||
GCC/ARM_CM85/non_secure/port.c
|
GCC/ARM_CM85/non_secure/port.c
|
||||||
GCC/ARM_CM85/non_secure/portasm.c
|
GCC/ARM_CM85/non_secure/portasm.c
|
||||||
|
|
@ -204,6 +226,28 @@ add_library(freertos_kernel_port OBJECT
|
||||||
GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_NONSECURE>:
|
||||||
|
GCC/ARM_STAR_MC3/non_secure/port.c
|
||||||
|
GCC/ARM_STAR_MC3/non_secure/portasm.c
|
||||||
|
GCC/ARM_STAR_MC3/non_secure/mpu_wrappers_v2_asm.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_SECURE>:
|
||||||
|
GCC/ARM_STAR_MC3/secure/secure_context_port.c
|
||||||
|
GCC/ARM_STAR_MC3/secure/secure_context.c
|
||||||
|
GCC/ARM_STAR_MC3/secure/secure_heap.c
|
||||||
|
GCC/ARM_STAR_MC3/secure/secure_init.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_NTZ_NONSECURE>:
|
||||||
|
GCC/ARM_STAR_MC3_NTZ/non_secure/port.c
|
||||||
|
GCC/ARM_STAR_MC3_NTZ/non_secure/portasm.c
|
||||||
|
GCC/ARM_STAR_MC3_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_TFM>:
|
||||||
|
GCC/ARM_STAR_MC3_NTZ/non_secure/port.c
|
||||||
|
GCC/ARM_STAR_MC3_NTZ/non_secure/portasm.c
|
||||||
|
GCC/ARM_STAR_MC3_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||||
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
# ARMv7-R ports for GCC
|
# ARMv7-R ports for GCC
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR5>:
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR5>:
|
||||||
GCC/ARM_CR5/port.c
|
GCC/ARM_CR5/port.c
|
||||||
|
|
@ -218,6 +262,12 @@ add_library(freertos_kernel_port OBJECT
|
||||||
GCC/ARM_CRx_No_GIC/port.c
|
GCC/ARM_CRx_No_GIC/port.c
|
||||||
GCC/ARM_CRx_No_GIC/portASM.S>
|
GCC/ARM_CRx_No_GIC/portASM.S>
|
||||||
|
|
||||||
|
# ARMv8-R ports for GCC
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR82>:
|
||||||
|
GCC/ARM_CR82/port.c
|
||||||
|
GCC/ARM_CR82/portASM.S
|
||||||
|
GCC/ARM_CR82/mpu_wrappers_v2_asm.c>
|
||||||
|
|
||||||
# ARMv4T ARM7TDMI ports for GCC
|
# ARMv4T ARM7TDMI ports for GCC
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM7_AT91FR40008>:
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM7_AT91FR40008>:
|
||||||
GCC/ARM7_AT91FR40008/port.c
|
GCC/ARM7_AT91FR40008/port.c
|
||||||
|
|
@ -498,6 +548,28 @@ add_library(freertos_kernel_port OBJECT
|
||||||
IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
||||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NONSECURE>:
|
||||||
|
IAR/ARM_CM52/non_secure/port.c
|
||||||
|
IAR/ARM_CM52/non_secure/portasm.s
|
||||||
|
IAR/ARM_CM52/non_secure/mpu_wrappers_v2_asm.S>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_SECURE>:
|
||||||
|
IAR/ARM_CM52/secure/secure_context_port_asm.s
|
||||||
|
IAR/ARM_CM52/secure/secure_context.c
|
||||||
|
IAR/ARM_CM52/secure/secure_heap.c
|
||||||
|
IAR/ARM_CM52/secure/secure_init.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NTZ_NONSECURE>:
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/portasm.s
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_TFM>:
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/portasm.s
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
||||||
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:
|
||||||
IAR/ARM_CM85/non_secure/port.c
|
IAR/ARM_CM85/non_secure/port.c
|
||||||
IAR/ARM_CM85/non_secure/portasm.s
|
IAR/ARM_CM85/non_secure/portasm.s
|
||||||
|
|
@ -520,6 +592,28 @@ add_library(freertos_kernel_port OBJECT
|
||||||
IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
||||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_NONSECURE>:
|
||||||
|
IAR/ARM_STAR_MC3/non_secure/port.c
|
||||||
|
IAR/ARM_STAR_MC3/non_secure/portasm.s
|
||||||
|
IAR/ARM_STAR_MC3/non_secure/mpu_wrappers_v2_asm.S>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_SECURE>:
|
||||||
|
IAR/ARM_STAR_MC3/secure/secure_context_port_asm.s
|
||||||
|
IAR/ARM_STAR_MC3/secure/secure_context.c
|
||||||
|
IAR/ARM_STAR_MC3/secure/secure_heap.c
|
||||||
|
IAR/ARM_STAR_MC3/secure/secure_init.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_NTZ_NONSECURE>:
|
||||||
|
IAR/ARM_STAR_MC3_NTZ/non_secure/port.c
|
||||||
|
IAR/ARM_STAR_MC3_NTZ/non_secure/portasm.s
|
||||||
|
IAR/ARM_STAR_MC3_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_TFM>:
|
||||||
|
IAR/ARM_STAR_MC3_NTZ/non_secure/port.c
|
||||||
|
IAR/ARM_STAR_MC3_NTZ/non_secure/portasm.s
|
||||||
|
IAR/ARM_STAR_MC3_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
||||||
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
# ARMv7-R Ports for IAR EWARM
|
# ARMv7-R Ports for IAR EWARM
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CRX_NOGIC>:
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CRX_NOGIC>:
|
||||||
IAR/ARM_CRx_No_GIC/port.c
|
IAR/ARM_CRx_No_GIC/port.c
|
||||||
|
|
@ -769,12 +863,14 @@ add_library(freertos_kernel_port OBJECT
|
||||||
if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR
|
if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR
|
||||||
FREERTOS_PORT STREQUAL "IAR_ARM_CM4F_MPU" OR
|
FREERTOS_PORT STREQUAL "IAR_ARM_CM4F_MPU" OR
|
||||||
FREERTOS_PORT STREQUAL "RVDS_ARM_CM4_MPU" OR
|
FREERTOS_PORT STREQUAL "RVDS_ARM_CM4_MPU" OR
|
||||||
FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR
|
FREERTOS_PORT STREQUAL "GCC_ARM_CRX_MPU" OR
|
||||||
FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NONSECURE" OR
|
FREERTOS_PORT MATCHES "GCC_ARM_(CM23|CM33|CM52|CM55|CM85|STAR_MC3)_NTZ_NONSECURE" OR
|
||||||
FREERTOS_PORT MATCHES "GCC_ARM_CM(33|55|85)_TFM" OR
|
FREERTOS_PORT MATCHES "GCC_ARM_(CM23|CM33|CM52|CM55|CM85|STAR_MC3)_NONSECURE" OR
|
||||||
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR
|
FREERTOS_PORT MATCHES "GCC_ARM_(CM33|CM52|CM55|CM85|STAR_MC3)_TFM" OR
|
||||||
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE" OR
|
FREERTOS_PORT MATCHES "GCC_ARM_CR82" OR
|
||||||
FREERTOS_PORT MATCHES "IAR_ARM_CM(33|55|85)_TFM"
|
FREERTOS_PORT MATCHES "IAR_ARM_(CM23|CM33|CM52|CM55|CM85|STAR_MC3)_NTZ_NONSECURE" OR
|
||||||
|
FREERTOS_PORT MATCHES "IAR_ARM_(CM23|CM33|CM52|CM55|CM85|STAR_MC3)_NONSECURE" OR
|
||||||
|
FREERTOS_PORT MATCHES "IAR_ARM_(CM33|CM52|CM55|CM85|STAR_MC3)_TFM"
|
||||||
)
|
)
|
||||||
target_sources(freertos_kernel_port PRIVATE
|
target_sources(freertos_kernel_port PRIVATE
|
||||||
Common/mpu_wrappers.c
|
Common/mpu_wrappers.c
|
||||||
|
|
@ -788,7 +884,7 @@ if (DEFINED FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG )
|
||||||
message(FATAL_ERROR "ARMv8.1-M PACBTI support in the kernel is not yet enabled for GNU toolchain due to known issues.")
|
message(FATAL_ERROR "ARMv8.1-M PACBTI support in the kernel is not yet enabled for GNU toolchain due to known issues.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FREERTOS_PORT MATCHES ".*ARM_CM85")
|
if(FREERTOS_PORT MATCHES ".*ARM_(CM52|CM85|STAR_MC3)")
|
||||||
if(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_STANDARD")
|
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 $<$<STREQUAL:${CMAKE_C_COMPILER_ID},ARMClang>:-mbranch-protection=standard>)
|
target_compile_options(freertos_kernel_port PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},ARMClang>:-mbranch-protection=standard>)
|
||||||
target_compile_options(freertos_kernel_port PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},IAR>:$<$<COMPILE_LANGUAGE:C,CXX>:--branch_protection=bti+pac-ret>>)
|
target_compile_options(freertos_kernel_port PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},IAR>:$<$<COMPILE_LANGUAGE:C,CXX>:--branch_protection=bti+pac-ret>>)
|
||||||
|
|
@ -875,7 +971,7 @@ if (DEFINED FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG )
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option is currently only supported on ARM Cortex-M85 FreeRTOS port.")
|
message(FATAL_ERROR "FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option is currently only supported on ARM Cortex-M85|M52 and Arm China STAR-MC3 FreeRTOS ports.")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -953,16 +1049,29 @@ target_include_directories(freertos_kernel_port_headers INTERFACE
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_SECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52/secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52_NTZ/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52_NTZ/non_secure>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_STAR_MC3/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_SECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_STAR_MC3/secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_STAR_MC3_NTZ/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_STAR_MC3_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_STAR_MC3_NTZ/non_secure>
|
||||||
|
|
||||||
# ARMv7-R ports for GCC
|
# ARMv7-R ports for GCC
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR5>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR5>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_MPU>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_MPU>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_MPU>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_MPU>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC>
|
||||||
|
|
||||||
|
# ARMv8-R ports for GCC
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR82>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR82>
|
||||||
|
|
||||||
# ARMv4T ARM7TDMI ports for GCC
|
# ARMv4T ARM7TDMI ports for GCC
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM7_AT91FR40008>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91FR40008>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM7_AT91FR40008>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91FR40008>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM7_AT91SAM7S>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91SAM7S>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM7_AT91SAM7S>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM7_AT91SAM7S>
|
||||||
|
|
@ -1085,11 +1194,21 @@ target_include_directories(freertos_kernel_port_headers INTERFACE
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_SECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52/secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52_NTZ/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52_NTZ/non_secure>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_STAR_MC3/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_SECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_STAR_MC3/secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_STAR_MC3_NTZ/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_STAR_MC3_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_STAR_MC3_NTZ/non_secure>
|
||||||
|
|
||||||
# ARMv7-R Ports for IAR EWARM
|
# ARMv7-R Ports for IAR EWARM
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CRX_NOGIC>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CRx_No_GIC>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CRX_NOGIC>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CRx_No_GIC>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1059,8 +1059,8 @@
|
||||||
configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* PRIVILEGED_FUNCTION */
|
configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
UBaseType_t uxReturn = 0;
|
UBaseType_t uxReturn = 0;
|
||||||
UBaseType_t xIsTaskStatusArrayWriteable = pdFALSE;
|
BaseType_t xIsTaskStatusArrayWriteable = pdFALSE;
|
||||||
UBaseType_t xIsTotalRunTimeWriteable = pdFALSE;
|
BaseType_t xIsTotalRunTimeWriteable = pdFALSE;
|
||||||
uint32_t ulArraySize = ( uint32_t ) uxArraySize;
|
uint32_t ulArraySize = ( uint32_t ) uxArraySize;
|
||||||
uint32_t ulTaskStatusSize = ( uint32_t ) sizeof( TaskStatus_t );
|
uint32_t ulTaskStatusSize = ( uint32_t ) sizeof( TaskStatus_t );
|
||||||
|
|
||||||
|
|
@ -4282,7 +4282,7 @@
|
||||||
#endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */
|
#endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */
|
const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
@ -4306,10 +4306,10 @@
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
#endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToSet,
|
const EventBits_t uxBitsToSet,
|
||||||
|
|
@ -4334,7 +4334,7 @@
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
#endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configUSE_EVENT_GROUPS == 1 )
|
#if ( configUSE_EVENT_GROUPS == 1 )
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
||||||
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -915,7 +917,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulSystemCallLocation, i;
|
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 )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -955,10 +960,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -981,7 +986,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1036,7 +1041,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulSystemCallLocation, i;
|
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 )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1072,10 +1080,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
||||||
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -484,7 +486,10 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulSystemCallLocation, i;
|
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 )
|
#if defined( __ARMCC_VERSION )
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* 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;
|
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ 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
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* 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.
|
/* Store the value of the Link Register before the SVC was raised.
|
||||||
* It contains the address of the caller of the System Call entry
|
* 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;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulSystemCallLocation, i;
|
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 )
|
#if defined( __ARMCC_VERSION )
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* 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;
|
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
||||||
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
@ -518,7 +520,7 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* 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;
|
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 )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -566,14 +572,14 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ 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
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* 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.
|
/* Store the value of the Link Register before the SVC was raised.
|
||||||
* It contains the address of the caller of the System Call entry
|
* 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;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* 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;
|
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 )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -688,14 +698,14 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2056
portable/GCC/ARM_CM52/non_secure/mpu_wrappers_v2_asm.c
Normal file
2056
portable/GCC/ARM_CM52/non_secure/mpu_wrappers_v2_asm.c
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/GCC/ARM_CM52/non_secure/port.c
Normal file
2280
portable/GCC/ARM_CM52/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
621
portable/GCC/ARM_CM52/non_secure/portasm.c
Normal file
621
portable/GCC/ARM_CM52/non_secure/portasm.c
Normal file
|
|
@ -0,0 +1,621 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" program_mpu_first_task: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs_first_task: \n"
|
||||||
|
" 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. */
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx lr \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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, =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. */
|
||||||
|
" 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. */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
" ite ne \n"
|
||||||
|
" 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. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
|
" nop \n"
|
||||||
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \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 up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .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. */
|
||||||
|
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||||
|
" \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" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
" \n"
|
||||||
|
" save_general_regs: \n"
|
||||||
|
" mrs r3, psp \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. */
|
||||||
|
" \n"
|
||||||
|
" save_special_regs: \n"
|
||||||
|
" mrs r3, psp \n" /* r3 = PSP. */
|
||||||
|
" 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. */
|
||||||
|
#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 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"
|
||||||
|
" program_mpu: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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, =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"
|
||||||
|
" restore_s_context: \n"
|
||||||
|
" push {r1-r3, lr} \n"
|
||||||
|
" bl SecureContext_LoadContext \n" /* 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"
|
||||||
|
" 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 */
|
||||||
|
" \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"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .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 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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"
|
||||||
|
" \n"
|
||||||
|
"tst lr, #4 \n"
|
||||||
|
"ite eq \n"
|
||||||
|
"mrseq r0, msp \n"
|
||||||
|
"mrsne r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
"ldr r1, [r0, #24] \n"
|
||||||
|
"ldrb r2, [r1, #-2] \n"
|
||||||
|
"cmp r2, %0 \n"
|
||||||
|
"blt syscall_enter \n"
|
||||||
|
"cmp r2, %1 \n"
|
||||||
|
"beq syscall_exit \n"
|
||||||
|
"b vPortSVCHandler_C \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_enter: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallEnter \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_exit: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
: /* No outputs. */
|
||||||
|
: "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
|
: "r0", "r1", "r2", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" tst lr, #4 \n"
|
||||||
|
" ite eq \n"
|
||||||
|
" mrseq r0, msp \n"
|
||||||
|
" mrsne r0, psp \n"
|
||||||
|
" ldr r1, =vPortSVCHandler_C \n"
|
||||||
|
" bx r1 \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||||
|
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||||
|
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||||
|
" it ne \n"
|
||||||
|
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
114
portable/GCC/ARM_CM52/non_secure/portasm.h
Normal file
114
portable/GCC/ARM_CM52/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
80
portable/GCC/ARM_CM52/non_secure/portmacro.h
Normal file
80
portable/GCC/ARM_CM52/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/GCC/ARM_CM52/non_secure/portmacrocommon.h
Normal file
582
portable/GCC/ARM_CM52/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_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.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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
|
||||||
|
|
||||||
|
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;
|
||||||
|
#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 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 portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
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 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR 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 * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_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 Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
354
portable/GCC/ARM_CM52/secure/secure_context.c
Normal file
354
portable/GCC/ARM_CM52/secure/secure_context.c
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Secure context includes. */
|
||||||
|
#include "secure_context.h"
|
||||||
|
|
||||||
|
/* Secure heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 0 --> Thread mode is privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for un-privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 1 --> Thread mode is un-privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Size of stack seal values in bytes.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_SIZE 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stack seal value as recommended by ARM.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum number of secure contexts.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||||
|
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pre-allocated array of secure contexts.
|
||||||
|
*/
|
||||||
|
SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a free secure context for a task from the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* This function ensures that only one secure context is allocated for a task.
|
||||||
|
*
|
||||||
|
* @param[in] pvTaskHandle The task handle for which the secure context is allocated.
|
||||||
|
*
|
||||||
|
* @return Index of a free secure context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the secure context to the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex );
|
||||||
|
|
||||||
|
/* These are implemented in assembly. */
|
||||||
|
extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Start with invalid index. */
|
||||||
|
uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackLimit == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackStart == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pvTaskHandle == NULL ) &&
|
||||||
|
( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = i;
|
||||||
|
}
|
||||||
|
else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* A task can only have one secure context. Do not allocate a second
|
||||||
|
* context for the same task. */
|
||||||
|
ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulSecureContextIndex;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex )
|
||||||
|
{
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, i;
|
||||||
|
static uint32_t ulSecureContextsInitialized = 0;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) )
|
||||||
|
{
|
||||||
|
/* Ensure to initialize secure contexts only once. */
|
||||||
|
ulSecureContextsInitialized = 1;
|
||||||
|
|
||||||
|
/* No stack for thread mode until a task's context is loaded. */
|
||||||
|
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||||
|
secureportSET_PSP( securecontextNO_STACK );
|
||||||
|
|
||||||
|
/* Initialize all secure contexts. */
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
xSecureContexts[ i ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ i ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be privileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
uint8_t * pucStackMemory = NULL;
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
uint32_t * pulCurrentStackPointer = NULL;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
|
||||||
|
* Register (PSPLIM) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode.
|
||||||
|
* Also do nothing, if a secure context us already loaded. PSPLIM is set to
|
||||||
|
* securecontextNO_STACK when no secure context is loaded. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) )
|
||||||
|
{
|
||||||
|
/* Obtain a free secure context. */
|
||||||
|
ulSecureContextIndex = ulGetSecureContext( pvTaskHandle );
|
||||||
|
|
||||||
|
/* Were we able to get a free context? */
|
||||||
|
if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
|
||||||
|
{
|
||||||
|
/* Allocate the stack space. */
|
||||||
|
pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE );
|
||||||
|
|
||||||
|
if( pucStackMemory != NULL )
|
||||||
|
{
|
||||||
|
/* Since stack grows down, the starting point will be the last
|
||||||
|
* location. Note that this location is next to the last
|
||||||
|
* allocated byte for stack (excluding the space for seal values)
|
||||||
|
* because the hardware decrements the stack pointer before
|
||||||
|
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||||
|
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||||
|
|
||||||
|
/* Seal the created secure process stack. */
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
|
||||||
|
/* The stack cannot go beyond this location. This value is
|
||||||
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
|
||||||
|
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
|
* This value is programmed in the CONTROL register on
|
||||||
|
* context switch. */
|
||||||
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
|
if( ulIsTaskPrivileged )
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the current stack pointer. This value is programmed in
|
||||||
|
* the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Current SP is set to the starting of the stack. This
|
||||||
|
* value programmed in the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Ensure to never return 0 as a valid context handle. */
|
||||||
|
xSecureContextHandle = ulSecureContextIndex + 1UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xSecureContextHandle;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* Only free if a valid context handle is passed. */
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
/* Ensure that the secure context being deleted is associated with
|
||||||
|
* the task. */
|
||||||
|
if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Free the stack space. */
|
||||||
|
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
|
||||||
|
|
||||||
|
/* Return the secure context back to the free secure contexts pool. */
|
||||||
|
vReturnSecureContext( ulSecureContextIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that no secure context is loaded and the task is loading it's
|
||||||
|
* own context. */
|
||||||
|
if( ( pucStackLimit == securecontextNO_STACK ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that task's context is loaded and the task is saving it's own
|
||||||
|
* context. */
|
||||||
|
if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
138
portable/GCC/ARM_CM52/secure/secure_context.h
Normal file
138
portable/GCC/ARM_CM52/secure/secure_context.h
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_CONTEXT_H__
|
||||||
|
#define __SECURE_CONTEXT_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PSP value when no secure context is loaded.
|
||||||
|
*/
|
||||||
|
#define securecontextNO_STACK 0x0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Invalid context ID.
|
||||||
|
*/
|
||||||
|
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure to represent a secure context.
|
||||||
|
*
|
||||||
|
* @note Since stack grows down, pucStackStart is the highest address while
|
||||||
|
* pucStackLimit is the first address of the allocated memory.
|
||||||
|
*/
|
||||||
|
typedef struct SecureContext
|
||||||
|
{
|
||||||
|
uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||||
|
uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||||
|
uint8_t * pucStackStart; /**< First location of the stack memory. */
|
||||||
|
void * pvTaskHandle; /**< Task handle of the task this context is associated with. */
|
||||||
|
} SecureContext_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opaque handle for a secure context.
|
||||||
|
*/
|
||||||
|
typedef uint32_t SecureContextHandle_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the secure context management system.
|
||||||
|
*
|
||||||
|
* PSP is set to NULL and therefore a task must allocate and load a context
|
||||||
|
* before calling any secure side function in the thread mode.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureContext_Init( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates a context on the secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
|
||||||
|
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
|
||||||
|
*
|
||||||
|
* @return Opaque context handle if context is successfully allocated, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||||
|
* context to be freed.
|
||||||
|
*/
|
||||||
|
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be loaded.
|
||||||
|
*/
|
||||||
|
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be saved.
|
||||||
|
*/
|
||||||
|
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
#endif /* __SECURE_CONTEXT_H__ */
|
||||||
97
portable/GCC/ARM_CM52/secure/secure_context_port.c
Normal file
97
portable/GCC/ARM_CM52/secure/secure_context_port.c
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Secure context includes. */
|
||||||
|
#include "secure_context.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||||
|
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
|
||||||
|
{
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||||
|
" cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
" ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||||
|
" msr control, r3 \n" /* CONTROL = r3. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
" \n"
|
||||||
|
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
||||||
|
" msr psp, r1 \n" /* PSP = r1. */
|
||||||
|
" \n"
|
||||||
|
" load_ctx_therad_mode: \n"
|
||||||
|
" bx lr \n"
|
||||||
|
" \n"
|
||||||
|
::: "r0", "r1", "r2"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext )
|
||||||
|
{
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||||
|
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
" mrs r1, psp \n" /* r1 = PSP. */
|
||||||
|
" \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */
|
||||||
|
" vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
" mrs r2, control \n" /* r2 = CONTROL. */
|
||||||
|
" stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
" \n"
|
||||||
|
" str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
|
||||||
|
" movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
|
||||||
|
" msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
|
||||||
|
" msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
||||||
|
" \n"
|
||||||
|
" save_ctx_therad_mode: \n"
|
||||||
|
" bx lr \n"
|
||||||
|
" \n"
|
||||||
|
::"i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
485
portable/GCC/ARM_CM52/secure/secure_heap.c
Normal file
485
portable/GCC/ARM_CM52/secure/secure_heap.c
Normal file
|
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* Configuration includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* Secure context heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total heap size.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigTOTAL_HEAP_SIZE
|
||||||
|
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No test marker by default. */
|
||||||
|
#ifndef mtCOVERAGE_TEST_MARKER
|
||||||
|
#define mtCOVERAGE_TEST_MARKER()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceMALLOC
|
||||||
|
#define traceMALLOC( pvReturn, xWantedSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceFREE
|
||||||
|
#define traceFREE( pv, xBlockSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Block sizes must not get too small. */
|
||||||
|
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
|
||||||
|
|
||||||
|
/* Assumes 8bit bytes! */
|
||||||
|
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||||
|
|
||||||
|
/* Max value that fits in a size_t type. */
|
||||||
|
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||||
|
|
||||||
|
/* Check if adding a and b will result in overflow. */
|
||||||
|
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||||
|
|
||||||
|
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||||
|
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||||
|
* an BlockLink_t structure is set then the block belongs to the application.
|
||||||
|
* When the bit is free the block is still part of the free heap space. */
|
||||||
|
#define secureheapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ) )
|
||||||
|
#define secureheapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) == 0 )
|
||||||
|
#define secureheapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) != 0 )
|
||||||
|
#define secureheapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
#define secureheapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The linked list structure.
|
||||||
|
*
|
||||||
|
* This is used to link free blocks in order of their memory address.
|
||||||
|
*/
|
||||||
|
typedef struct A_BLOCK_LINK
|
||||||
|
{
|
||||||
|
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
|
||||||
|
size_t xBlockSize; /**< The size of the free block. */
|
||||||
|
} BlockLink_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called automatically to setup the required heap structures the first
|
||||||
|
* time pvPortMalloc() is called.
|
||||||
|
*/
|
||||||
|
static void prvHeapInit( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a block of memory that is being freed into the correct
|
||||||
|
* position in the list of free memory blocks.
|
||||||
|
*
|
||||||
|
* The block being freed will be merged with the block in front it and/or the
|
||||||
|
* block behind it if the memory blocks are adjacent to each other.
|
||||||
|
*
|
||||||
|
* @param[in] pxBlockToInsert The block being freed.
|
||||||
|
*/
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The size of the structure placed at the beginning of each allocated
|
||||||
|
* memory block must by correctly byte aligned.
|
||||||
|
*/
|
||||||
|
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a couple of list links to mark the start and end of the list.
|
||||||
|
*/
|
||||||
|
static BlockLink_t xStart;
|
||||||
|
static BlockLink_t * pxEnd = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
||||||
|
* about fragmentation.
|
||||||
|
*/
|
||||||
|
static size_t xFreeBytesRemaining = 0U;
|
||||||
|
static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHeapInit( void )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxFirstFreeBlock;
|
||||||
|
uint8_t * pucAlignedHeap;
|
||||||
|
size_t uxAddress;
|
||||||
|
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
|
|
||||||
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
|
uxAddress = ( size_t ) ucHeap;
|
||||||
|
|
||||||
|
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
|
||||||
|
{
|
||||||
|
uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
pucAlignedHeap = ( uint8_t * ) uxAddress;
|
||||||
|
|
||||||
|
/* xStart is used to hold a pointer to the first item in the list of free
|
||||||
|
* blocks. The void cast is used to prevent compiler warnings. */
|
||||||
|
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
xStart.xBlockSize = ( size_t ) 0;
|
||||||
|
|
||||||
|
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
||||||
|
* at the end of the heap space. */
|
||||||
|
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
|
||||||
|
uxAddress -= xHeapStructSize;
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
pxEnd = ( void * ) uxAddress;
|
||||||
|
pxEnd->xBlockSize = 0;
|
||||||
|
pxEnd->pxNextFreeBlock = NULL;
|
||||||
|
|
||||||
|
/* To start with there is a single free block that is sized to take up the
|
||||||
|
* entire heap space, minus the space taken by pxEnd. */
|
||||||
|
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
|
||||||
|
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
||||||
|
|
||||||
|
/* Only one block exists - and it covers the entire usable heap space. */
|
||||||
|
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxIterator;
|
||||||
|
uint8_t * puc;
|
||||||
|
|
||||||
|
/* Iterate through the list until a block is found that has a higher address
|
||||||
|
* than the block being inserted. */
|
||||||
|
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
/* Nothing to do here, just iterate to the right position. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted after
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxIterator;
|
||||||
|
|
||||||
|
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||||
|
pxBlockToInsert = pxIterator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted before
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxBlockToInsert;
|
||||||
|
|
||||||
|
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Form one big block from the two blocks. */
|
||||||
|
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
if( pxIterator != pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void * pvPortMalloc( size_t xWantedSize )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxBlock;
|
||||||
|
BlockLink_t * pxPreviousBlock;
|
||||||
|
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. */
|
||||||
|
if( pxEnd == NULL )
|
||||||
|
{
|
||||||
|
prvHeapInit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xWantedSize > 0 )
|
||||||
|
{
|
||||||
|
/* The wanted size must be increased so it can contain a BlockLink_t
|
||||||
|
* structure in addition to the requested amount of bytes. */
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xHeapStructSize;
|
||||||
|
|
||||||
|
/* Ensure that blocks are always aligned to the required number
|
||||||
|
* of bytes. */
|
||||||
|
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
|
||||||
|
{
|
||||||
|
/* Byte alignment required. */
|
||||||
|
xAdditionalRequiredSize = secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xAdditionalRequiredSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the requested block size is not so large that the top bit is set.
|
||||||
|
* The top bit of the block size member of the BlockLink_t structure is used
|
||||||
|
* to determine who owns the block - the application or the kernel, so it
|
||||||
|
* must be free. */
|
||||||
|
if( secureheapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
|
||||||
|
{
|
||||||
|
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
||||||
|
{
|
||||||
|
/* Traverse the list from the start (lowest address) block until
|
||||||
|
* one of adequate size is found. */
|
||||||
|
pxPreviousBlock = &xStart;
|
||||||
|
pxBlock = xStart.pxNextFreeBlock;
|
||||||
|
|
||||||
|
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||||
|
{
|
||||||
|
pxPreviousBlock = pxBlock;
|
||||||
|
pxBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the end marker was reached then a block of adequate size was
|
||||||
|
* not found. */
|
||||||
|
if( pxBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Return the memory space pointed to - jumping over the
|
||||||
|
* BlockLink_t structure at its start. */
|
||||||
|
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
|
||||||
|
|
||||||
|
/* This block is being returned for use so must be taken out
|
||||||
|
* of the list of free blocks. */
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
|
||||||
|
/* If the block is larger than required it can be split into
|
||||||
|
* two. */
|
||||||
|
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
|
||||||
|
{
|
||||||
|
/* This block is to be split into two. Create a new
|
||||||
|
* block following the number of bytes requested. The void
|
||||||
|
* cast is used to prevent byte alignment warnings from the
|
||||||
|
* compiler. */
|
||||||
|
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
|
||||||
|
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
||||||
|
/* Calculate the sizes of two blocks split from the single
|
||||||
|
* block. */
|
||||||
|
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
||||||
|
pxBlock->xBlockSize = xWantedSize;
|
||||||
|
|
||||||
|
/* Insert the new block into the list of free blocks. */
|
||||||
|
pxNewBlockLink->pxNextFreeBlock = pxPreviousBlock->pxNextFreeBlock;
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxNewBlockLink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||||
|
|
||||||
|
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
|
||||||
|
{
|
||||||
|
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
pxBlock->pxNextFreeBlock = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
traceMALLOC( pvReturn, xAllocatedBlockSize );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xAllocatedBlockSize;
|
||||||
|
|
||||||
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
|
{
|
||||||
|
extern void vApplicationMallocFailedHook( void );
|
||||||
|
vApplicationMallocFailedHook();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
return pvReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFree( void * pv )
|
||||||
|
{
|
||||||
|
uint8_t * puc = ( uint8_t * ) pv;
|
||||||
|
BlockLink_t * pxLink;
|
||||||
|
|
||||||
|
if( pv != NULL )
|
||||||
|
{
|
||||||
|
/* The memory being freed will have an BlockLink_t structure immediately
|
||||||
|
* before it. */
|
||||||
|
puc -= xHeapStructSize;
|
||||||
|
|
||||||
|
/* This casting is to keep the compiler from issuing warnings. */
|
||||||
|
pxLink = ( void * ) puc;
|
||||||
|
|
||||||
|
/* Check the block is actually allocated. */
|
||||||
|
secureportASSERT( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
|
||||||
|
secureportASSERT( pxLink->pxNextFreeBlock == NULL );
|
||||||
|
|
||||||
|
if( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
|
||||||
|
{
|
||||||
|
if( pxLink->pxNextFreeBlock == NULL )
|
||||||
|
{
|
||||||
|
/* The block is being returned to the heap - it is no longer
|
||||||
|
* allocated. */
|
||||||
|
secureheapFREE_BLOCK( pxLink );
|
||||||
|
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
/* Add this block to the list of free blocks. */
|
||||||
|
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||||
|
traceFREE( pv, pxLink->xBlockSize );
|
||||||
|
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||||
|
}
|
||||||
|
secureportENABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xMinimumEverFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
66
portable/GCC/ARM_CM52/secure/secure_heap.h
Normal file
66
portable/GCC/ARM_CM52/secure/secure_heap.h
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_HEAP_H__
|
||||||
|
#define __SECURE_HEAP_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates memory from heap.
|
||||||
|
*
|
||||||
|
* @param[in] xWantedSize The size of the memory to be allocated.
|
||||||
|
*
|
||||||
|
* @return Pointer to the memory region if the allocation is successful, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
void * pvPortMalloc( size_t xWantedSize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the previously allocated memory.
|
||||||
|
*
|
||||||
|
* @param[in] pv Pointer to the memory to be freed.
|
||||||
|
*/
|
||||||
|
void vPortFree( void * pv );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the free heap size.
|
||||||
|
*
|
||||||
|
* @return Free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetFreeHeapSize( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the minimum ever free heap size.
|
||||||
|
*
|
||||||
|
* @return Minimum ever free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_HEAP_H__ */
|
||||||
106
portable/GCC/ARM_CM52/secure/secure_init.c
Normal file
106
portable/GCC/ARM_CM52/secure/secure_init.c
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* Secure init includes. */
|
||||||
|
#include "secure_init.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the SCB.
|
||||||
|
*/
|
||||||
|
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the FPU.
|
||||||
|
*/
|
||||||
|
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
|
||||||
|
#define secureinitFPCCR_LSPENS_POS ( 29UL )
|
||||||
|
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
|
||||||
|
#define secureinitFPCCR_TS_POS ( 26UL )
|
||||||
|
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
|
||||||
|
|
||||||
|
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
|
||||||
|
#define secureinitNSACR_CP10_POS ( 10UL )
|
||||||
|
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
|
||||||
|
#define secureinitNSACR_CP11_POS ( 11UL )
|
||||||
|
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
|
||||||
|
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
|
||||||
|
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
|
||||||
|
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||||
|
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||||
|
|
||||||
|
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||||
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
|
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
||||||
|
* registers (S16-S31) are also pushed to stack on exception entry and
|
||||||
|
* restored on exception return. */
|
||||||
|
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
54
portable/GCC/ARM_CM52/secure/secure_init.h
Normal file
54
portable/GCC/ARM_CM52/secure/secure_init.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_INIT_H__
|
||||||
|
#define __SECURE_INIT_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-prioritizes the non-secure exceptions.
|
||||||
|
*
|
||||||
|
* This is needed to ensure that the non-secure PendSV runs at the lowest
|
||||||
|
* priority. Context switch is done in the non-secure PendSV handler.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_DePrioritizeNSExceptions( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets up the Floating Point Unit (FPU) for Non-Secure access.
|
||||||
|
*
|
||||||
|
* Also sets FPCCR.TS=1 to ensure that the content of the Floating Point
|
||||||
|
* Registers are not leaked to the non-secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_EnableNSFPUAccess( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_INIT_H__ */
|
||||||
140
portable/GCC/ARM_CM52/secure/secure_port_macros.h
Normal file
140
portable/GCC/ARM_CM52/secure/secure_port_macros.h
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_PORT_MACROS_H__
|
||||||
|
#define __SECURE_PORT_MACROS_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Byte alignment requirements.
|
||||||
|
*/
|
||||||
|
#define secureportBYTE_ALIGNMENT 8
|
||||||
|
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Macro to declare a function as non-secure callable.
|
||||||
|
*/
|
||||||
|
#if defined( __IAR_SYSTEMS_ICC__ )
|
||||||
|
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
||||||
|
#else
|
||||||
|
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the non-secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSP value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSP( pucCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSPLIM value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSPLIM( pucOutStackLimit ) \
|
||||||
|
__asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSPLIM to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSPLIM( pucStackLimit ) \
|
||||||
|
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the NonSecure MSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_MSP_NS( pucMainStackPointer ) \
|
||||||
|
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the CONTROL register to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_CONTROL( ulControl ) \
|
||||||
|
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the Interrupt Program Status Register (IPSR) value in the given
|
||||||
|
* variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_IPSR( ulIPSR ) \
|
||||||
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to enable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to disable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable non-secure interrupts.
|
||||||
|
*
|
||||||
|
* This effectively disables context switches.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable non-secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert definition.
|
||||||
|
*/
|
||||||
|
#define secureportASSERT( x ) \
|
||||||
|
if( ( x ) == 0 ) \
|
||||||
|
{ \
|
||||||
|
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||||
|
for( ; ; ) {; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||||
2055
portable/GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c
Normal file
2055
portable/GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/GCC/ARM_CM52_NTZ/non_secure/port.c
Normal file
2280
portable/GCC/ARM_CM52_NTZ/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
524
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.c
Normal file
524
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.c
Normal file
|
|
@ -0,0 +1,524 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" program_mpu_first_task: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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"
|
||||||
|
" msr control, r4 \n"
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs_first_task: \n"
|
||||||
|
" 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. */
|
||||||
|
" \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. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx lr \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" 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. */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
" ite ne \n"
|
||||||
|
" 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. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
|
" nop \n"
|
||||||
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \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 up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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 */
|
||||||
|
" 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. */
|
||||||
|
" \n"
|
||||||
|
" save_special_regs: \n"
|
||||||
|
" 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 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"
|
||||||
|
" program_mpu: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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"
|
||||||
|
" msr control, r4 \n"
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs: \n"
|
||||||
|
" 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 */
|
||||||
|
" \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"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \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 */
|
||||||
|
" \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"
|
||||||
|
#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 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, =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 */
|
||||||
|
" \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"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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"
|
||||||
|
" \n"
|
||||||
|
"tst lr, #4 \n"
|
||||||
|
"ite eq \n"
|
||||||
|
"mrseq r0, msp \n"
|
||||||
|
"mrsne r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
"ldr r1, [r0, #24] \n"
|
||||||
|
"ldrb r2, [r1, #-2] \n"
|
||||||
|
"cmp r2, %0 \n"
|
||||||
|
"blt syscall_enter \n"
|
||||||
|
"cmp r2, %1 \n"
|
||||||
|
"beq syscall_exit \n"
|
||||||
|
"b vPortSVCHandler_C \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_enter: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallEnter \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_exit: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
: /* No outputs. */
|
||||||
|
: "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
|
: "r0", "r1", "r2", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" tst lr, #4 \n"
|
||||||
|
" ite eq \n"
|
||||||
|
" mrseq r0, msp \n"
|
||||||
|
" mrsne r0, psp \n"
|
||||||
|
" ldr r1, =vPortSVCHandler_C \n"
|
||||||
|
" bx r1 \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
114
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.h
Normal file
114
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
80
portable/GCC/ARM_CM52_NTZ/non_secure/portmacro.h
Normal file
80
portable/GCC/ARM_CM52_NTZ/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/GCC/ARM_CM52_NTZ/non_secure/portmacrocommon.h
Normal file
582
portable/GCC/ARM_CM52_NTZ/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_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.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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
|
||||||
|
|
||||||
|
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;
|
||||||
|
#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 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 portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
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 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR 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 * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_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 Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
* 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
|
* Copyright 2024-2025 Arm Limited and/or its affiliates
|
||||||
* <open-source-office@arm.com>
|
* <open-source-office@arm.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
|
|
@ -230,7 +230,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
#if ( portARMV8M_MINOR_VERSION >= 1 )
|
||||||
|
|
||||||
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
/* Enable Privileged eXecute Never MPU attribute for the selected memory
|
||||||
* region. */
|
* region. */
|
||||||
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
|
||||||
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
#endif /* portARMV8M_MINOR_VERSION >= 1 */
|
||||||
|
|
@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void );
|
||||||
/* Enable MPU. */
|
/* Enable MPU. */
|
||||||
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
||||||
/* Expected value of the portMPU_TYPE register. */
|
|
||||||
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
|
|
||||||
|
|
||||||
/* Extract first address of the MPU region as encoded in the
|
/* Extract first address of the MPU region as encoded in the
|
||||||
* RBAR (Region Base Address Register) value. */
|
* RBAR (Region Base Address Register) value. */
|
||||||
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
|
||||||
|
|
@ -291,7 +288,7 @@ typedef void ( * portISR_t )( void );
|
||||||
|
|
||||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -308,7 +305,7 @@ typedef void ( * portISR_t )( void );
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -401,7 +398,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract MPU region's access permissions from the Region Base Address
|
* @brief Extract MPU region's access permissions from the Region Base Address
|
||||||
* Register (RBAR) value.
|
* Register (RBAR) value.
|
||||||
*
|
*
|
||||||
|
|
@ -414,7 +411,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -422,7 +419,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -430,7 +427,7 @@ static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures PACBTI features.
|
* @brief Configures PACBTI features.
|
||||||
*
|
*
|
||||||
* This function configures the Pointer Authentication, and Branch Target
|
* This function configures the Pointer Authentication, and Branch Target
|
||||||
|
|
@ -491,7 +488,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up the system call stack so that upon returning from
|
* @brief Sets up the system call stack so that upon returning from
|
||||||
* SVC, the system call stack is used.
|
* SVC, the system call stack is used.
|
||||||
*
|
*
|
||||||
|
|
@ -507,7 +504,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -516,7 +513,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( 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
|
* @brief Sets up the task stack so that upon returning from
|
||||||
* SVC, the task stack is used again.
|
* SVC, the task stack is used again.
|
||||||
*
|
*
|
||||||
|
|
@ -530,7 +527,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the calling task is privileged.
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
|
@ -542,7 +539,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV
|
||||||
|
|
||||||
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
#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;
|
PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
@ -557,7 +554,7 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
|
|
@ -579,18 +576,18 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
#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;
|
PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -925,12 +922,6 @@ static void prvTaskExitError( void )
|
||||||
/* The only permitted number of regions are 8 or 16. */
|
/* The only permitted number of regions are 8 or 16. */
|
||||||
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 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 );
|
|
||||||
|
|
||||||
/* Check that the MPU is present. */
|
|
||||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
|
||||||
{
|
|
||||||
/* MAIR0 - Index 0. */
|
/* MAIR0 - Index 0. */
|
||||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||||
/* MAIR0 - Index 1. */
|
/* MAIR0 - Index 1. */
|
||||||
|
|
@ -983,7 +974,6 @@ static void prvTaskExitError( void )
|
||||||
* regions have privileged access. */
|
* regions have privileged access. */
|
||||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulSystemCallStack;
|
uint32_t * pulSystemCallStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the system call stack for the stack frame. */
|
/* Make space on the system call stack for the stack frame. */
|
||||||
pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
|
pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
pulSystemCallStack[ i ] = pulTaskStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
|
|
||||||
/* Remember the location where we should copy the stack frame when we exit from
|
/* Remember the location where we should copy the stack frame when we exit from
|
||||||
* the system call. */
|
* the system call. */
|
||||||
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
|
pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Record if the hardware used padding to force the stack pointer
|
/* Record if the hardware used padding to force the stack pointer
|
||||||
* to be double word aligned. */
|
* to be double word aligned. */
|
||||||
|
|
@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
extern TaskHandle_t pxCurrentTCB;
|
extern TaskHandle_t pxCurrentTCB;
|
||||||
xMPU_SETTINGS * pxMpuSettings;
|
xMPU_SETTINGS * pxMpuSettings;
|
||||||
uint32_t * pulTaskStack;
|
uint32_t * pulTaskStack;
|
||||||
uint32_t ulStackFrameSize, ulSystemCallLocation, i;
|
uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
|
|
@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
{
|
{
|
||||||
pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
|
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 ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
{
|
{
|
||||||
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
|
||||||
{
|
{
|
||||||
/* Extended frame i.e. FPU in use. */
|
/* Extended frame i.e. FPU in use. */
|
||||||
ulStackFrameSize = 26;
|
ulHardwareSavedExceptionFrameSize = 26;
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" vpush {s0} \n" /* Trigger lazy stacking. */
|
" vpush {s0} \n" /* Trigger lazy stacking. */
|
||||||
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
" vpop {s0} \n" /* Nullify the affect of the above instruction. */
|
||||||
|
|
@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Standard frame i.e. FPU not in use. */
|
/* Standard frame i.e. FPU not in use. */
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
#else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
{
|
{
|
||||||
ulStackFrameSize = 8;
|
ulHardwareSavedExceptionFrameSize = 8;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
/* Make space on the task stack for the stack frame. */
|
/* Make space on the task stack for the stack frame. */
|
||||||
pulTaskStack = pulTaskStack - ulStackFrameSize;
|
pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize;
|
||||||
|
|
||||||
/* Copy the stack frame. */
|
/* Copy the stack frame. */
|
||||||
for( i = 0; i < ulStackFrameSize; i++ )
|
for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ )
|
||||||
{
|
{
|
||||||
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
pulTaskStack[ i ] = pulSystemCallStack[ i ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
48
portable/GCC/ARM_CR82/README.md
Normal file
48
portable/GCC/ARM_CR82/README.md
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
# 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).
|
||||||
|
|
||||||
|
# MPU Support
|
||||||
|
|
||||||
|
- This port supports the FreeRTOS MPU on both single-core and SMP (multi-core) configurations. Enable via `configENABLE_MPU = 1`; the port programs MPU regions per task on each active core.
|
||||||
|
|
||||||
|
- Minimum MPU granularity and alignment: 64 bytes. Ensure any user‑defined region base and size are 64‑byte aligned.
|
||||||
|
|
||||||
|
# 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` (i.e., `portSVC_START_FIRST_TASK`) to enter `FreeRTOS_SWI_Handler`, which will call `vPortRestoreContext()` based on the SVC number to start scheduling on this core.
|
||||||
944
portable/GCC/ARM_CR82/mpu_wrappers_v2_asm.c
Normal file
944
portable/GCC/ARM_CR82/mpu_wrappers_v2_asm.c
Normal file
|
|
@ -0,0 +1,944 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2025 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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"
|
||||||
|
#include "portmacro.h"
|
||||||
|
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common single-SVC dispatch: wrappers do only one SVC.
|
||||||
|
* The SVC handler decides whether to tail-call the implementation directly
|
||||||
|
* (privileged) or set up full system-call state (unprivileged).
|
||||||
|
*/
|
||||||
|
#define FREERTOS_MPU_SVC_DISPATCH( xSystemCallNumber ) \
|
||||||
|
__asm volatile ( \
|
||||||
|
"svc %0 \n" \
|
||||||
|
: \
|
||||||
|
: "i" ( xSystemCallNumber ) \
|
||||||
|
: "memory" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskDelayUntil );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskAbortDelay );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTaskDelay );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxTaskPriorityGet );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_eTaskGetState );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTaskGetInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGetIdleTaskHandle );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTaskSuspend );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTaskResume );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGetTickCount );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxTaskGetNumberOfTasks );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_ulTaskGetRunTimeCounter );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_ulTaskGetRunTimePercent );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_ulTaskGetIdleRunTimePercent );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_ulTaskGetIdleRunTimeCounter );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTaskSetApplicationTaskTag );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGetApplicationTaskTag );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTaskSetThreadLocalStoragePointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxTaskGetSystemState );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxTaskGetStackHighWaterMark );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxTaskGetStackHighWaterMark2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGetCurrentTaskHandle );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGetSchedulerState );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTaskSetTimeOutState );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskCheckForTimeOut );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGenericNotify );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGenericNotifyWait );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_ulTaskGenericNotifyTake );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTaskGenericNotifyStateClear );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_ulTaskGenericNotifyValueClear );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueGenericSend );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxQueueMessagesWaiting );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxQueueSpacesAvailable );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueReceive );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueuePeek );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueSemaphoreTake );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueGetMutexHolder );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueTakeMutexRecursive );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueGiveMutexRecursive );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueSelectFromSet );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xQueueAddToSet );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vQueueAddToRegistry );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vQueueUnregisterQueue );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_pcQueueGetName );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_pvTimerGetTimerID );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTimerSetTimerID );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTimerIsTimerActive );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTimerGenericCommandFromTask );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_pcTimerGetName );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vTimerSetReloadMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTimerGetReloadMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxTimerGetReloadMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTimerGetPeriod );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xTimerGetExpiryTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_EVENT_GROUPS == 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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( 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 ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( 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 ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( 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,
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xEventGroupSync );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_EVENT_GROUPS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configUSE_EVENT_GROUPS == 1 ) && ( 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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_uxEventGroupGetNumber );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( 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;
|
||||||
|
|
||||||
|
void MPU_vEventGroupSetNumber( void * xEventGroup,
|
||||||
|
UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_vEventGroupSetNumber );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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,
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( 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,
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xStreamBufferReceive );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_STREAM_BUFFERS == 1 )
|
||||||
|
|
||||||
|
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xStreamBufferIsFull );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_STREAM_BUFFERS == 1 )
|
||||||
|
|
||||||
|
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xStreamBufferIsEmpty );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_STREAM_BUFFERS == 1 )
|
||||||
|
|
||||||
|
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xStreamBufferSpacesAvailable );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_STREAM_BUFFERS == 1 )
|
||||||
|
|
||||||
|
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xStreamBufferBytesAvailable );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_STREAM_BUFFERS == 1 )
|
||||||
|
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xStreamBufferSetTriggerLevel );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_STREAM_BUFFERS == 1 )
|
||||||
|
|
||||||
|
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */
|
||||||
|
{
|
||||||
|
FREERTOS_MPU_SVC_DISPATCH( SYSTEM_CALL_xStreamBufferNextMessageLengthBytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if ( configUSE_STREAM_BUFFERS == 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) */
|
||||||
1786
portable/GCC/ARM_CR82/port.c
Normal file
1786
portable/GCC/ARM_CR82/port.c
Normal file
File diff suppressed because it is too large
Load diff
1159
portable/GCC/ARM_CR82/portASM.S
Normal file
1159
portable/GCC/ARM_CR82/portASM.S
Normal file
File diff suppressed because it is too large
Load diff
541
portable/GCC/ARM_CR82/portmacro.h
Normal file
541
portable/GCC/ARM_CR82/portmacro.h
Normal file
|
|
@ -0,0 +1,541 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2025-2026 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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_SYSTEM_CALL_EXIT 104
|
||||||
|
#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 portSVC_CHECK_PRIVILEGE 113
|
||||||
|
#define portSVC_SAVE_TASK_CONTEXT 114
|
||||||
|
#define portSVC_RESTORE_CONTEXT 115
|
||||||
|
#define portSVC_DELETE_CURRENT_TASK 116
|
||||||
|
#define portSVC_INTERRUPT_CORE 117
|
||||||
|
|
||||||
|
#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, uint8_t ucCoreID );
|
||||||
|
#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 )
|
||||||
|
#define portMAX_API_PRIORITY_MASK ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT )
|
||||||
|
|
||||||
|
#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( uint8_t ucCoreID,
|
||||||
|
ePortRTOSLock eLockNum,
|
||||||
|
BaseType_t uxAcquire );
|
||||||
|
extern uint8_t ucPortGetCoreID( void );
|
||||||
|
extern uint8_t ucPortGetCoreIDFromIsr( 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() ucPortGetCoreID()
|
||||||
|
#define portGET_CORE_ID_FROM_ISR() ucPortGetCoreIDFromIsr()
|
||||||
|
|
||||||
|
/* Use SGI 0 as the yield core interrupt. */
|
||||||
|
#define portYIELD_CORE( xCoreID ) vInterruptCore( portYIELD_CORE_INT_ID, ( uint8_t ) xCoreID )
|
||||||
|
|
||||||
|
#define portRELEASE_ISR_LOCK( xCoreID ) vPortRecursiveLock( ( uint8_t ) xCoreID, eIsrLock, pdFALSE )
|
||||||
|
#define portGET_ISR_LOCK( xCoreID ) vPortRecursiveLock( ( uint8_t ) xCoreID, eIsrLock, pdTRUE )
|
||||||
|
|
||||||
|
#define portRELEASE_TASK_LOCK( xCoreID ) vPortRecursiveLock( ( uint8_t ) xCoreID, eTaskLock, pdFALSE )
|
||||||
|
#define portGET_TASK_LOCK( xCoreID ) vPortRecursiveLock( ( uint8_t ) xCoreID, eTaskLock, pdTRUE )
|
||||||
|
#define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( ullCriticalNestings[ ( uint8_t ) xCoreID ] )
|
||||||
|
#define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( ullCriticalNestings[ ( uint8_t ) xCoreID ] = ( x ) )
|
||||||
|
#define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( ullCriticalNestings[ ( uint8_t ) xCoreID ]++ )
|
||||||
|
#define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( ullCriticalNestings[ ( uint8_t ) xCoreID ]-- )
|
||||||
|
|
||||||
|
#endif /* configNUMBER_OF_CORES > 1 */
|
||||||
|
|
||||||
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU specific constants.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
#if !defined(__ASSEMBLER__)
|
||||||
|
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||||
|
#endif /* if !defined(__ASSEMBLER__) */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MAIR_EL1 registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 )
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 )
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 )
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C )
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 16UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0ULL ) /* Privileged flash region number. */
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1ULL ) /* Unprivileged flash region number. */
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2ULL ) /* Unprivileged syscalls region number. */
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3ULL ) /* Privileged RAM region number. */
|
||||||
|
#define portSTACK_REGION ( 4ULL ) /* Stack region number. */
|
||||||
|
#define portSTACK_REGION_INDEX ( 0ULL ) /* Stack region index in the xRegionSettings array. */
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5ULL ) /* First user configurable region number. */
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||||
|
#define portACL_ENTRY_SIZE_BITS ( 32UL )
|
||||||
|
#endif /* configENABLE_ACCESS_CONTROL_LIST == 1 */
|
||||||
|
|
||||||
|
#if !defined(__ASSEMBLER__)
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint64_t ullPrbarEl1; /**< PRBAR_EL1 for the region. */
|
||||||
|
uint64_t ullPrlarEl1; /**< PRLAR_EL1 for the region. */
|
||||||
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
|
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||||
|
#define configSYSTEM_CALL_STACK_SIZE 128 /* must be defined to the desired size of the system call stack in words for using MPU wrappers v2. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System call info.
|
||||||
|
*/
|
||||||
|
typedef struct SYSTEM_CALL_INFO
|
||||||
|
{
|
||||||
|
/* Used to save both the user-mode stack pointer (SP_EL0) and link register (X30)
|
||||||
|
* at system call entry so they can be restored or referenced safely even if the task
|
||||||
|
* switches out while executing the system call.
|
||||||
|
*/
|
||||||
|
uint64_t ullLinkRegisterAtSystemCallEntry;
|
||||||
|
uint64_t ullUserSPAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_INFO;
|
||||||
|
#endif /* if !defined(__ASSEMBLER__) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task context as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_FPU == 1 )
|
||||||
|
/*
|
||||||
|
* +-----------+------------+--------------------------------+-------------+------------------+
|
||||||
|
* | Q0-Q31 | FPSR, FPCR | CRITICAL_NESTING, FPU_CONTEXT | X0-X30, XZR | INIT_PSTATE, PC |
|
||||||
|
* +-----------+------------+--------------------------------+-------------+------------------+
|
||||||
|
*
|
||||||
|
* <-----------><-----------><-------------------------------><------------><----------------->
|
||||||
|
* 64 2 2 32 2
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 102
|
||||||
|
|
||||||
|
#else /* #if ( configENABLE_FPU == 1 ) */
|
||||||
|
/*
|
||||||
|
* +--------------------------------+-------------+------------------+
|
||||||
|
* | CRITICAL_NESTING, FPU_CONTEXT | X0-X30, XZR | INIT_PSTATE, PC |
|
||||||
|
* +--------------------------------+-------------+------------------+
|
||||||
|
* <-------------------------------><------------><------------------>
|
||||||
|
* 2 32 2
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 36
|
||||||
|
#endif /* #if ( configENABLE_FPU == 1 ) */
|
||||||
|
|
||||||
|
#if !defined(__ASSEMBLER__)
|
||||||
|
typedef struct MPU_SETTINGS
|
||||||
|
{
|
||||||
|
uint64_t ullTaskUnprivilegedSP; /* Task's unprivileged user stack pointer. */
|
||||||
|
uint64_t ullMairEl1; /* MAIR_EL1 for the task containing attributes. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /* Settings for tasks' regions. */
|
||||||
|
uint64_t ullContext[ MAX_CONTEXT_SIZE + configSYSTEM_CALL_STACK_SIZE ]; /* Task's saved context. */
|
||||||
|
uint64_t ullTaskFlags;
|
||||||
|
|
||||||
|
xSYSTEM_CALL_INFO xSystemCallInfo;
|
||||||
|
|
||||||
|
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||||
|
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
|
||||||
|
#endif /* configENABLE_ACCESS_CONTROL_LIST */
|
||||||
|
} xMPU_SETTINGS;
|
||||||
|
#endif /* if !defined(__ASSEMBLER__) */
|
||||||
|
|
||||||
|
#define portUSING_MPU_WRAPPERS ( 1 )
|
||||||
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MAIR_EL1 registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR0_POS ( 0UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR0_MASK ( 0x00000000000000ffULL )
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR1_POS ( 8UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR1_MASK ( 0x000000000000ff00ULL )
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR2_POS ( 16UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR2_MASK ( 0x0000000000ff0000ULL )
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR3_POS ( 24UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR3_MASK ( 0x00000000ff000000ULL )
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR4_POS ( 32UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR4_MASK ( 0x000000ff00000000ULL )
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR5_POS ( 40UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR5_MASK ( 0x0000ff0000000000ULL )
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR6_POS ( 48UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR6_MASK ( 0x00ff000000000000ULL )
|
||||||
|
|
||||||
|
#define portMPU_MAIR_EL1_ATTR7_POS ( 56UL )
|
||||||
|
#define portMPU_MAIR_EL1_ATTR7_MASK ( 0xff00000000000000ULL )
|
||||||
|
|
||||||
|
#define portMPU_PRBAR_EL1_ADDRESS_MASK ( 0x0000FFFFFFFFFFC0ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ADDRESS_MASK ( 0x0000FFFFFFFFFFC0ULL )
|
||||||
|
#define portMPU_PRBAR_EL1_ACCESS_PERMISSIONS_MASK ( 3ULL<< 2ULL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0ULL << 4ULL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2ULL << 4ULL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 3ULL << 4ULL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0ULL << 2ULL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1ULL << 2ULL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2ULL << 2ULL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3ULL << 2ULL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1ULL << 1ULL )
|
||||||
|
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX0 ( 0ULL << 1ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX1 ( 1ULL << 1ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX2 ( 2ULL << 1ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX3 ( 3ULL << 1ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX4 ( 4ULL << 1ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX5 ( 5ULL << 1ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX6 ( 6ULL << 1ULL )
|
||||||
|
#define portMPU_PRLAR_EL1_ATTR_INDEX7 ( 7ULL << 1ULL )
|
||||||
|
|
||||||
|
#define portMPU_PRLAR_EL1_REGION_ENABLE ( 1ULL )
|
||||||
|
|
||||||
|
#define portMPU_ENABLE_BIT ( 1ULL << 0ULL )
|
||||||
|
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1ULL << 17ULL )
|
||||||
|
|
||||||
|
/* Max value that fits in a uint64_t type. */
|
||||||
|
#define portUINT64_MAX ( ~( ( uint64_t ) 0 ) )
|
||||||
|
#define portADD_UINT64_WILL_OVERFLOW( a, b ) ( ( a ) > ( portUINT64_MAX - ( b ) ) )
|
||||||
|
|
||||||
|
/* Extract first address of the MPU region as encoded in the
|
||||||
|
* PRBAR_EL1 register value. */
|
||||||
|
#define portEXTRACT_FIRST_ADDRESS_FROM_PRBAR_EL1( prbar_el1 ) \
|
||||||
|
( ( prbar_el1 ) & portMPU_PRBAR_EL1_ADDRESS_MASK )
|
||||||
|
|
||||||
|
/* Extract last address of the MPU region as encoded in the
|
||||||
|
* PRLAR_EL1 register value. */
|
||||||
|
#define portEXTRACT_LAST_ADDRESS_FROM_PRLAR_EL1( prlar_el1 ) \
|
||||||
|
( ( ( prlar_el1 ) & portMPU_PRLAR_EL1_ADDRESS_MASK ) | ~portMPU_PRLAR_EL1_ADDRESS_MASK )
|
||||||
|
|
||||||
|
/* 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 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Offsets in the task's stack (context).
|
||||||
|
*/
|
||||||
|
#if ( configUSE_TASK_FPU_SUPPORT == portTASK_HAVE_FPU_CONTEXT_BY_DEFAULT )
|
||||||
|
#define portOFFSET_TO_PC ( 68 )
|
||||||
|
#define portOFFSET_TO_LR ( 70 )
|
||||||
|
#define portOFFSET_TO_X0 ( 100 )
|
||||||
|
#define portOFFSET_TO_X1 ( 101 )
|
||||||
|
#define portOFFSET_TO_X2 ( 98 )
|
||||||
|
#define portOFFSET_TO_X3 ( 99 )
|
||||||
|
#else
|
||||||
|
#define portOFFSET_TO_PC ( 2 )
|
||||||
|
#define portOFFSET_TO_LR ( 4 )
|
||||||
|
#define portOFFSET_TO_X0 ( 34 )
|
||||||
|
#define portOFFSET_TO_X1 ( 35 )
|
||||||
|
#define portOFFSET_TO_X2 ( 32 )
|
||||||
|
#define portOFFSET_TO_X3 ( 33 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flag used to mark that a Task is privileged.
|
||||||
|
*
|
||||||
|
* @ingroup Port Privilege
|
||||||
|
*/
|
||||||
|
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
|
|
||||||
|
#endif /* #if ( configENABLE_MPU == 1 ) */
|
||||||
|
|
||||||
|
#define portPSTATE_I_BIT ( 0x7 )
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
.arm
|
.arm
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.section freertos_system_calls
|
.section freertos_system_calls, "ax"
|
||||||
|
|
||||||
#define FREERTOS_ASSEMBLY
|
#define FREERTOS_ASSEMBLY
|
||||||
#include "FreeRTOSConfig.h"
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
|
||||||
|
|
@ -418,7 +418,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||||
ulIndex = portSTACK_REGION;
|
ulIndex = portSTACK_REGION;
|
||||||
xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack;
|
xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack;
|
||||||
xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
|
xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
|
||||||
portMPU_REGION_ENABLE );;
|
portMPU_REGION_ENABLE );
|
||||||
xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC |
|
xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC |
|
||||||
portMPU_REGION_NORMAL_OIWTNOWA_SHARED );
|
portMPU_REGION_NORMAL_OIWTNOWA_SHARED );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
.arm
|
.arm
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.section privileged_functions
|
.section privileged_functions, "ax"
|
||||||
|
|
||||||
#define FREERTOS_ASSEMBLY
|
#define FREERTOS_ASSEMBLY
|
||||||
#include "portmacro_asm.h"
|
#include "portmacro_asm.h"
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,11 @@
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */
|
#ifdef __ARMEB__
|
||||||
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x21f ) /* System mode, ARM mode, IRQ enabled FIQ enabled, Big-endian. */
|
||||||
|
#else
|
||||||
|
#define portINITIAL_SPSR ( ( StackType_t ) 0x01f ) /* System mode, ARM mode, IRQ enabled FIQ enabled, Little-endian. */
|
||||||
|
#endif
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||||
|
|
||||||
|
|
|
||||||
2056
portable/GCC/ARM_STAR_MC3/non_secure/mpu_wrappers_v2_asm.c
Normal file
2056
portable/GCC/ARM_STAR_MC3/non_secure/mpu_wrappers_v2_asm.c
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/GCC/ARM_STAR_MC3/non_secure/port.c
Normal file
2280
portable/GCC/ARM_STAR_MC3/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
621
portable/GCC/ARM_STAR_MC3/non_secure/portasm.c
Normal file
621
portable/GCC/ARM_STAR_MC3/non_secure/portasm.c
Normal file
|
|
@ -0,0 +1,621 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" program_mpu_first_task: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs_first_task: \n"
|
||||||
|
" 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. */
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx lr \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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, =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. */
|
||||||
|
" 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. */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
" ite ne \n"
|
||||||
|
" 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. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
|
" nop \n"
|
||||||
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \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 up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .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. */
|
||||||
|
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||||
|
" \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" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
" \n"
|
||||||
|
" save_general_regs: \n"
|
||||||
|
" mrs r3, psp \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. */
|
||||||
|
" \n"
|
||||||
|
" save_special_regs: \n"
|
||||||
|
" mrs r3, psp \n" /* r3 = PSP. */
|
||||||
|
" 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. */
|
||||||
|
#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 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"
|
||||||
|
" program_mpu: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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, =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"
|
||||||
|
" restore_s_context: \n"
|
||||||
|
" push {r1-r3, lr} \n"
|
||||||
|
" bl SecureContext_LoadContext \n" /* 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"
|
||||||
|
" 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 */
|
||||||
|
" \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"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .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 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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"
|
||||||
|
" \n"
|
||||||
|
"tst lr, #4 \n"
|
||||||
|
"ite eq \n"
|
||||||
|
"mrseq r0, msp \n"
|
||||||
|
"mrsne r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
"ldr r1, [r0, #24] \n"
|
||||||
|
"ldrb r2, [r1, #-2] \n"
|
||||||
|
"cmp r2, %0 \n"
|
||||||
|
"blt syscall_enter \n"
|
||||||
|
"cmp r2, %1 \n"
|
||||||
|
"beq syscall_exit \n"
|
||||||
|
"b vPortSVCHandler_C \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_enter: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallEnter \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_exit: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
: /* No outputs. */
|
||||||
|
: "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
|
: "r0", "r1", "r2", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" tst lr, #4 \n"
|
||||||
|
" ite eq \n"
|
||||||
|
" mrseq r0, msp \n"
|
||||||
|
" mrsne r0, psp \n"
|
||||||
|
" ldr r1, =vPortSVCHandler_C \n"
|
||||||
|
" bx r1 \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||||
|
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||||
|
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||||
|
" it ne \n"
|
||||||
|
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
114
portable/GCC/ARM_STAR_MC3/non_secure/portasm.h
Normal file
114
portable/GCC/ARM_STAR_MC3/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
80
portable/GCC/ARM_STAR_MC3/non_secure/portmacro.h
Normal file
80
portable/GCC/ARM_STAR_MC3/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2026 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "STAR-MC3"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/GCC/ARM_STAR_MC3/non_secure/portmacrocommon.h
Normal file
582
portable/GCC/ARM_STAR_MC3/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_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.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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
|
||||||
|
|
||||||
|
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;
|
||||||
|
#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 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 portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
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 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR 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 * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_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 Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
354
portable/GCC/ARM_STAR_MC3/secure/secure_context.c
Normal file
354
portable/GCC/ARM_STAR_MC3/secure/secure_context.c
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Secure context includes. */
|
||||||
|
#include "secure_context.h"
|
||||||
|
|
||||||
|
/* Secure heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 0 --> Thread mode is privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for un-privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 1 --> Thread mode is un-privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Size of stack seal values in bytes.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_SIZE 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stack seal value as recommended by ARM.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum number of secure contexts.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||||
|
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pre-allocated array of secure contexts.
|
||||||
|
*/
|
||||||
|
SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a free secure context for a task from the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* This function ensures that only one secure context is allocated for a task.
|
||||||
|
*
|
||||||
|
* @param[in] pvTaskHandle The task handle for which the secure context is allocated.
|
||||||
|
*
|
||||||
|
* @return Index of a free secure context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the secure context to the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex );
|
||||||
|
|
||||||
|
/* These are implemented in assembly. */
|
||||||
|
extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Start with invalid index. */
|
||||||
|
uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackLimit == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackStart == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pvTaskHandle == NULL ) &&
|
||||||
|
( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = i;
|
||||||
|
}
|
||||||
|
else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* A task can only have one secure context. Do not allocate a second
|
||||||
|
* context for the same task. */
|
||||||
|
ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulSecureContextIndex;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex )
|
||||||
|
{
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, i;
|
||||||
|
static uint32_t ulSecureContextsInitialized = 0;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) )
|
||||||
|
{
|
||||||
|
/* Ensure to initialize secure contexts only once. */
|
||||||
|
ulSecureContextsInitialized = 1;
|
||||||
|
|
||||||
|
/* No stack for thread mode until a task's context is loaded. */
|
||||||
|
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||||
|
secureportSET_PSP( securecontextNO_STACK );
|
||||||
|
|
||||||
|
/* Initialize all secure contexts. */
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
xSecureContexts[ i ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ i ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be privileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
uint8_t * pucStackMemory = NULL;
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
uint32_t * pulCurrentStackPointer = NULL;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
|
||||||
|
* Register (PSPLIM) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode.
|
||||||
|
* Also do nothing, if a secure context us already loaded. PSPLIM is set to
|
||||||
|
* securecontextNO_STACK when no secure context is loaded. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) )
|
||||||
|
{
|
||||||
|
/* Obtain a free secure context. */
|
||||||
|
ulSecureContextIndex = ulGetSecureContext( pvTaskHandle );
|
||||||
|
|
||||||
|
/* Were we able to get a free context? */
|
||||||
|
if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
|
||||||
|
{
|
||||||
|
/* Allocate the stack space. */
|
||||||
|
pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE );
|
||||||
|
|
||||||
|
if( pucStackMemory != NULL )
|
||||||
|
{
|
||||||
|
/* Since stack grows down, the starting point will be the last
|
||||||
|
* location. Note that this location is next to the last
|
||||||
|
* allocated byte for stack (excluding the space for seal values)
|
||||||
|
* because the hardware decrements the stack pointer before
|
||||||
|
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||||
|
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||||
|
|
||||||
|
/* Seal the created secure process stack. */
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
|
||||||
|
/* The stack cannot go beyond this location. This value is
|
||||||
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
|
||||||
|
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
|
* This value is programmed in the CONTROL register on
|
||||||
|
* context switch. */
|
||||||
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
|
if( ulIsTaskPrivileged )
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the current stack pointer. This value is programmed in
|
||||||
|
* the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Current SP is set to the starting of the stack. This
|
||||||
|
* value programmed in the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Ensure to never return 0 as a valid context handle. */
|
||||||
|
xSecureContextHandle = ulSecureContextIndex + 1UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xSecureContextHandle;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* Only free if a valid context handle is passed. */
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
/* Ensure that the secure context being deleted is associated with
|
||||||
|
* the task. */
|
||||||
|
if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Free the stack space. */
|
||||||
|
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
|
||||||
|
|
||||||
|
/* Return the secure context back to the free secure contexts pool. */
|
||||||
|
vReturnSecureContext( ulSecureContextIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that no secure context is loaded and the task is loading it's
|
||||||
|
* own context. */
|
||||||
|
if( ( pucStackLimit == securecontextNO_STACK ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that task's context is loaded and the task is saving it's own
|
||||||
|
* context. */
|
||||||
|
if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
138
portable/GCC/ARM_STAR_MC3/secure/secure_context.h
Normal file
138
portable/GCC/ARM_STAR_MC3/secure/secure_context.h
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_CONTEXT_H__
|
||||||
|
#define __SECURE_CONTEXT_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PSP value when no secure context is loaded.
|
||||||
|
*/
|
||||||
|
#define securecontextNO_STACK 0x0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Invalid context ID.
|
||||||
|
*/
|
||||||
|
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure to represent a secure context.
|
||||||
|
*
|
||||||
|
* @note Since stack grows down, pucStackStart is the highest address while
|
||||||
|
* pucStackLimit is the first address of the allocated memory.
|
||||||
|
*/
|
||||||
|
typedef struct SecureContext
|
||||||
|
{
|
||||||
|
uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||||
|
uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||||
|
uint8_t * pucStackStart; /**< First location of the stack memory. */
|
||||||
|
void * pvTaskHandle; /**< Task handle of the task this context is associated with. */
|
||||||
|
} SecureContext_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opaque handle for a secure context.
|
||||||
|
*/
|
||||||
|
typedef uint32_t SecureContextHandle_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the secure context management system.
|
||||||
|
*
|
||||||
|
* PSP is set to NULL and therefore a task must allocate and load a context
|
||||||
|
* before calling any secure side function in the thread mode.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureContext_Init( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates a context on the secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
|
||||||
|
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
|
||||||
|
*
|
||||||
|
* @return Opaque context handle if context is successfully allocated, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||||
|
* context to be freed.
|
||||||
|
*/
|
||||||
|
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be loaded.
|
||||||
|
*/
|
||||||
|
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be saved.
|
||||||
|
*/
|
||||||
|
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
#endif /* __SECURE_CONTEXT_H__ */
|
||||||
97
portable/GCC/ARM_STAR_MC3/secure/secure_context_port.c
Normal file
97
portable/GCC/ARM_STAR_MC3/secure/secure_context_port.c
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Secure context includes. */
|
||||||
|
#include "secure_context.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||||
|
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
|
||||||
|
{
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||||
|
" cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
" ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||||
|
" msr control, r3 \n" /* CONTROL = r3. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
" \n"
|
||||||
|
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
||||||
|
" msr psp, r1 \n" /* PSP = r1. */
|
||||||
|
" \n"
|
||||||
|
" load_ctx_therad_mode: \n"
|
||||||
|
" bx lr \n"
|
||||||
|
" \n"
|
||||||
|
::: "r0", "r1", "r2"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext )
|
||||||
|
{
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||||
|
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
" mrs r1, psp \n" /* r1 = PSP. */
|
||||||
|
" \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */
|
||||||
|
" vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
" mrs r2, control \n" /* r2 = CONTROL. */
|
||||||
|
" stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
" \n"
|
||||||
|
" str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
|
||||||
|
" movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
|
||||||
|
" msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
|
||||||
|
" msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
||||||
|
" \n"
|
||||||
|
" save_ctx_therad_mode: \n"
|
||||||
|
" bx lr \n"
|
||||||
|
" \n"
|
||||||
|
::"i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
485
portable/GCC/ARM_STAR_MC3/secure/secure_heap.c
Normal file
485
portable/GCC/ARM_STAR_MC3/secure/secure_heap.c
Normal file
|
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* Configuration includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* Secure context heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total heap size.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigTOTAL_HEAP_SIZE
|
||||||
|
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No test marker by default. */
|
||||||
|
#ifndef mtCOVERAGE_TEST_MARKER
|
||||||
|
#define mtCOVERAGE_TEST_MARKER()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceMALLOC
|
||||||
|
#define traceMALLOC( pvReturn, xWantedSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceFREE
|
||||||
|
#define traceFREE( pv, xBlockSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Block sizes must not get too small. */
|
||||||
|
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
|
||||||
|
|
||||||
|
/* Assumes 8bit bytes! */
|
||||||
|
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||||
|
|
||||||
|
/* Max value that fits in a size_t type. */
|
||||||
|
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||||
|
|
||||||
|
/* Check if adding a and b will result in overflow. */
|
||||||
|
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||||
|
|
||||||
|
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||||
|
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||||
|
* an BlockLink_t structure is set then the block belongs to the application.
|
||||||
|
* When the bit is free the block is still part of the free heap space. */
|
||||||
|
#define secureheapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ) )
|
||||||
|
#define secureheapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) == 0 )
|
||||||
|
#define secureheapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) != 0 )
|
||||||
|
#define secureheapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
#define secureheapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The linked list structure.
|
||||||
|
*
|
||||||
|
* This is used to link free blocks in order of their memory address.
|
||||||
|
*/
|
||||||
|
typedef struct A_BLOCK_LINK
|
||||||
|
{
|
||||||
|
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
|
||||||
|
size_t xBlockSize; /**< The size of the free block. */
|
||||||
|
} BlockLink_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called automatically to setup the required heap structures the first
|
||||||
|
* time pvPortMalloc() is called.
|
||||||
|
*/
|
||||||
|
static void prvHeapInit( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a block of memory that is being freed into the correct
|
||||||
|
* position in the list of free memory blocks.
|
||||||
|
*
|
||||||
|
* The block being freed will be merged with the block in front it and/or the
|
||||||
|
* block behind it if the memory blocks are adjacent to each other.
|
||||||
|
*
|
||||||
|
* @param[in] pxBlockToInsert The block being freed.
|
||||||
|
*/
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The size of the structure placed at the beginning of each allocated
|
||||||
|
* memory block must by correctly byte aligned.
|
||||||
|
*/
|
||||||
|
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a couple of list links to mark the start and end of the list.
|
||||||
|
*/
|
||||||
|
static BlockLink_t xStart;
|
||||||
|
static BlockLink_t * pxEnd = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
||||||
|
* about fragmentation.
|
||||||
|
*/
|
||||||
|
static size_t xFreeBytesRemaining = 0U;
|
||||||
|
static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHeapInit( void )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxFirstFreeBlock;
|
||||||
|
uint8_t * pucAlignedHeap;
|
||||||
|
size_t uxAddress;
|
||||||
|
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
|
|
||||||
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
|
uxAddress = ( size_t ) ucHeap;
|
||||||
|
|
||||||
|
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
|
||||||
|
{
|
||||||
|
uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
pucAlignedHeap = ( uint8_t * ) uxAddress;
|
||||||
|
|
||||||
|
/* xStart is used to hold a pointer to the first item in the list of free
|
||||||
|
* blocks. The void cast is used to prevent compiler warnings. */
|
||||||
|
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
xStart.xBlockSize = ( size_t ) 0;
|
||||||
|
|
||||||
|
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
||||||
|
* at the end of the heap space. */
|
||||||
|
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
|
||||||
|
uxAddress -= xHeapStructSize;
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
pxEnd = ( void * ) uxAddress;
|
||||||
|
pxEnd->xBlockSize = 0;
|
||||||
|
pxEnd->pxNextFreeBlock = NULL;
|
||||||
|
|
||||||
|
/* To start with there is a single free block that is sized to take up the
|
||||||
|
* entire heap space, minus the space taken by pxEnd. */
|
||||||
|
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
|
||||||
|
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
||||||
|
|
||||||
|
/* Only one block exists - and it covers the entire usable heap space. */
|
||||||
|
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxIterator;
|
||||||
|
uint8_t * puc;
|
||||||
|
|
||||||
|
/* Iterate through the list until a block is found that has a higher address
|
||||||
|
* than the block being inserted. */
|
||||||
|
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
/* Nothing to do here, just iterate to the right position. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted after
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxIterator;
|
||||||
|
|
||||||
|
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||||
|
pxBlockToInsert = pxIterator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted before
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxBlockToInsert;
|
||||||
|
|
||||||
|
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Form one big block from the two blocks. */
|
||||||
|
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
if( pxIterator != pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void * pvPortMalloc( size_t xWantedSize )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxBlock;
|
||||||
|
BlockLink_t * pxPreviousBlock;
|
||||||
|
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. */
|
||||||
|
if( pxEnd == NULL )
|
||||||
|
{
|
||||||
|
prvHeapInit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xWantedSize > 0 )
|
||||||
|
{
|
||||||
|
/* The wanted size must be increased so it can contain a BlockLink_t
|
||||||
|
* structure in addition to the requested amount of bytes. */
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xHeapStructSize;
|
||||||
|
|
||||||
|
/* Ensure that blocks are always aligned to the required number
|
||||||
|
* of bytes. */
|
||||||
|
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
|
||||||
|
{
|
||||||
|
/* Byte alignment required. */
|
||||||
|
xAdditionalRequiredSize = secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xAdditionalRequiredSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the requested block size is not so large that the top bit is set.
|
||||||
|
* The top bit of the block size member of the BlockLink_t structure is used
|
||||||
|
* to determine who owns the block - the application or the kernel, so it
|
||||||
|
* must be free. */
|
||||||
|
if( secureheapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
|
||||||
|
{
|
||||||
|
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
||||||
|
{
|
||||||
|
/* Traverse the list from the start (lowest address) block until
|
||||||
|
* one of adequate size is found. */
|
||||||
|
pxPreviousBlock = &xStart;
|
||||||
|
pxBlock = xStart.pxNextFreeBlock;
|
||||||
|
|
||||||
|
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||||
|
{
|
||||||
|
pxPreviousBlock = pxBlock;
|
||||||
|
pxBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the end marker was reached then a block of adequate size was
|
||||||
|
* not found. */
|
||||||
|
if( pxBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Return the memory space pointed to - jumping over the
|
||||||
|
* BlockLink_t structure at its start. */
|
||||||
|
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
|
||||||
|
|
||||||
|
/* This block is being returned for use so must be taken out
|
||||||
|
* of the list of free blocks. */
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
|
||||||
|
/* If the block is larger than required it can be split into
|
||||||
|
* two. */
|
||||||
|
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
|
||||||
|
{
|
||||||
|
/* This block is to be split into two. Create a new
|
||||||
|
* block following the number of bytes requested. The void
|
||||||
|
* cast is used to prevent byte alignment warnings from the
|
||||||
|
* compiler. */
|
||||||
|
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
|
||||||
|
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
||||||
|
/* Calculate the sizes of two blocks split from the single
|
||||||
|
* block. */
|
||||||
|
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
||||||
|
pxBlock->xBlockSize = xWantedSize;
|
||||||
|
|
||||||
|
/* Insert the new block into the list of free blocks. */
|
||||||
|
pxNewBlockLink->pxNextFreeBlock = pxPreviousBlock->pxNextFreeBlock;
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxNewBlockLink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||||
|
|
||||||
|
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
|
||||||
|
{
|
||||||
|
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
pxBlock->pxNextFreeBlock = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
traceMALLOC( pvReturn, xAllocatedBlockSize );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xAllocatedBlockSize;
|
||||||
|
|
||||||
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
|
{
|
||||||
|
extern void vApplicationMallocFailedHook( void );
|
||||||
|
vApplicationMallocFailedHook();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
return pvReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFree( void * pv )
|
||||||
|
{
|
||||||
|
uint8_t * puc = ( uint8_t * ) pv;
|
||||||
|
BlockLink_t * pxLink;
|
||||||
|
|
||||||
|
if( pv != NULL )
|
||||||
|
{
|
||||||
|
/* The memory being freed will have an BlockLink_t structure immediately
|
||||||
|
* before it. */
|
||||||
|
puc -= xHeapStructSize;
|
||||||
|
|
||||||
|
/* This casting is to keep the compiler from issuing warnings. */
|
||||||
|
pxLink = ( void * ) puc;
|
||||||
|
|
||||||
|
/* Check the block is actually allocated. */
|
||||||
|
secureportASSERT( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
|
||||||
|
secureportASSERT( pxLink->pxNextFreeBlock == NULL );
|
||||||
|
|
||||||
|
if( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
|
||||||
|
{
|
||||||
|
if( pxLink->pxNextFreeBlock == NULL )
|
||||||
|
{
|
||||||
|
/* The block is being returned to the heap - it is no longer
|
||||||
|
* allocated. */
|
||||||
|
secureheapFREE_BLOCK( pxLink );
|
||||||
|
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
/* Add this block to the list of free blocks. */
|
||||||
|
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||||
|
traceFREE( pv, pxLink->xBlockSize );
|
||||||
|
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||||
|
}
|
||||||
|
secureportENABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xMinimumEverFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
66
portable/GCC/ARM_STAR_MC3/secure/secure_heap.h
Normal file
66
portable/GCC/ARM_STAR_MC3/secure/secure_heap.h
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_HEAP_H__
|
||||||
|
#define __SECURE_HEAP_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates memory from heap.
|
||||||
|
*
|
||||||
|
* @param[in] xWantedSize The size of the memory to be allocated.
|
||||||
|
*
|
||||||
|
* @return Pointer to the memory region if the allocation is successful, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
void * pvPortMalloc( size_t xWantedSize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the previously allocated memory.
|
||||||
|
*
|
||||||
|
* @param[in] pv Pointer to the memory to be freed.
|
||||||
|
*/
|
||||||
|
void vPortFree( void * pv );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the free heap size.
|
||||||
|
*
|
||||||
|
* @return Free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetFreeHeapSize( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the minimum ever free heap size.
|
||||||
|
*
|
||||||
|
* @return Minimum ever free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_HEAP_H__ */
|
||||||
106
portable/GCC/ARM_STAR_MC3/secure/secure_init.c
Normal file
106
portable/GCC/ARM_STAR_MC3/secure/secure_init.c
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* Secure init includes. */
|
||||||
|
#include "secure_init.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the SCB.
|
||||||
|
*/
|
||||||
|
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the FPU.
|
||||||
|
*/
|
||||||
|
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
|
||||||
|
#define secureinitFPCCR_LSPENS_POS ( 29UL )
|
||||||
|
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
|
||||||
|
#define secureinitFPCCR_TS_POS ( 26UL )
|
||||||
|
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
|
||||||
|
|
||||||
|
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
|
||||||
|
#define secureinitNSACR_CP10_POS ( 10UL )
|
||||||
|
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
|
||||||
|
#define secureinitNSACR_CP11_POS ( 11UL )
|
||||||
|
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
|
||||||
|
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
|
||||||
|
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
|
||||||
|
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||||
|
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||||
|
|
||||||
|
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||||
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
|
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
||||||
|
* registers (S16-S31) are also pushed to stack on exception entry and
|
||||||
|
* restored on exception return. */
|
||||||
|
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
54
portable/GCC/ARM_STAR_MC3/secure/secure_init.h
Normal file
54
portable/GCC/ARM_STAR_MC3/secure/secure_init.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_INIT_H__
|
||||||
|
#define __SECURE_INIT_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-prioritizes the non-secure exceptions.
|
||||||
|
*
|
||||||
|
* This is needed to ensure that the non-secure PendSV runs at the lowest
|
||||||
|
* priority. Context switch is done in the non-secure PendSV handler.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_DePrioritizeNSExceptions( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets up the Floating Point Unit (FPU) for Non-Secure access.
|
||||||
|
*
|
||||||
|
* Also sets FPCCR.TS=1 to ensure that the content of the Floating Point
|
||||||
|
* Registers are not leaked to the non-secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_EnableNSFPUAccess( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_INIT_H__ */
|
||||||
140
portable/GCC/ARM_STAR_MC3/secure/secure_port_macros.h
Normal file
140
portable/GCC/ARM_STAR_MC3/secure/secure_port_macros.h
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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 __SECURE_PORT_MACROS_H__
|
||||||
|
#define __SECURE_PORT_MACROS_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Byte alignment requirements.
|
||||||
|
*/
|
||||||
|
#define secureportBYTE_ALIGNMENT 8
|
||||||
|
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Macro to declare a function as non-secure callable.
|
||||||
|
*/
|
||||||
|
#if defined( __IAR_SYSTEMS_ICC__ )
|
||||||
|
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
||||||
|
#else
|
||||||
|
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the non-secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSP value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSP( pucCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSPLIM value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSPLIM( pucOutStackLimit ) \
|
||||||
|
__asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSPLIM to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSPLIM( pucStackLimit ) \
|
||||||
|
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the NonSecure MSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_MSP_NS( pucMainStackPointer ) \
|
||||||
|
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the CONTROL register to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_CONTROL( ulControl ) \
|
||||||
|
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the Interrupt Program Status Register (IPSR) value in the given
|
||||||
|
* variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_IPSR( ulIPSR ) \
|
||||||
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to enable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to disable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable non-secure interrupts.
|
||||||
|
*
|
||||||
|
* This effectively disables context switches.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable non-secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert definition.
|
||||||
|
*/
|
||||||
|
#define secureportASSERT( x ) \
|
||||||
|
if( ( x ) == 0 ) \
|
||||||
|
{ \
|
||||||
|
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||||
|
for( ; ; ) {; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||||
2055
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/mpu_wrappers_v2_asm.c
Normal file
2055
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/mpu_wrappers_v2_asm.c
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c
Normal file
2280
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
524
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portasm.c
Normal file
524
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portasm.c
Normal file
|
|
@ -0,0 +1,524 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" program_mpu_first_task: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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"
|
||||||
|
" msr control, r4 \n"
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs_first_task: \n"
|
||||||
|
" 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. */
|
||||||
|
" \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. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx lr \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" 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. */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
" ite ne \n"
|
||||||
|
" 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. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
|
" nop \n"
|
||||||
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \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 up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" 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 */
|
||||||
|
" 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. */
|
||||||
|
" \n"
|
||||||
|
" save_special_regs: \n"
|
||||||
|
" 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 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"
|
||||||
|
" program_mpu: \n"
|
||||||
|
" 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, =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, =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, =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 */
|
||||||
|
" \n"
|
||||||
|
" 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, =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"
|
||||||
|
" msr control, r4 \n"
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs: \n"
|
||||||
|
" 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 */
|
||||||
|
" \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"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \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 */
|
||||||
|
" \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"
|
||||||
|
#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 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, =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 */
|
||||||
|
" \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"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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"
|
||||||
|
" \n"
|
||||||
|
"tst lr, #4 \n"
|
||||||
|
"ite eq \n"
|
||||||
|
"mrseq r0, msp \n"
|
||||||
|
"mrsne r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
"ldr r1, [r0, #24] \n"
|
||||||
|
"ldrb r2, [r1, #-2] \n"
|
||||||
|
"cmp r2, %0 \n"
|
||||||
|
"blt syscall_enter \n"
|
||||||
|
"cmp r2, %1 \n"
|
||||||
|
"beq syscall_exit \n"
|
||||||
|
"b vPortSVCHandler_C \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_enter: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallEnter \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_exit: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
: /* No outputs. */
|
||||||
|
: "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
|
: "r0", "r1", "r2", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" tst lr, #4 \n"
|
||||||
|
" ite eq \n"
|
||||||
|
" mrseq r0, msp \n"
|
||||||
|
" mrsne r0, psp \n"
|
||||||
|
" ldr r1, =vPortSVCHandler_C \n"
|
||||||
|
" bx r1 \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
114
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portasm.h
Normal file
114
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
80
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portmacro.h
Normal file
80
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2026 Arm Technology (China) Co., Ltd.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* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "STAR-MC3"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portmacrocommon.h
Normal file
582
portable/GCC/ARM_STAR_MC3_NTZ/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* 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 PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_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.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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
|
||||||
|
|
||||||
|
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;
|
||||||
|
#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 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 portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
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 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR 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 * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 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
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_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 Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 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 ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
|
|
@ -90,7 +90,7 @@ void vPortSetupTimerInterrupt( void ) __attribute__( ( weak ) );
|
||||||
uint64_t ullNextTime = 0ULL;
|
uint64_t ullNextTime = 0ULL;
|
||||||
const uint64_t * pullNextTime = &ullNextTime;
|
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. */
|
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */
|
||||||
uint64_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
|
UBaseType_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
|
||||||
volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
||||||
|
|
||||||
/* Holds the critical nesting value - deliberately non-zero at start up to
|
/* Holds the critical nesting value - deliberately non-zero at start up to
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,6 @@ definitions. */
|
||||||
* where the global and thread pointers are currently assumed to be constant so
|
* where the global and thread pointers are currently assumed to be constant so
|
||||||
* are not saved:
|
* are not saved:
|
||||||
*
|
*
|
||||||
* mstatus
|
|
||||||
* xCriticalNesting
|
* xCriticalNesting
|
||||||
* x31
|
* x31
|
||||||
* x30
|
* x30
|
||||||
|
|
@ -192,18 +191,13 @@ definitions. */
|
||||||
* x6
|
* x6
|
||||||
* x5
|
* x5
|
||||||
* portTASK_RETURN_ADDRESS
|
* portTASK_RETURN_ADDRESS
|
||||||
|
* [FPU registers (when enabled/available) go here]
|
||||||
|
* [VPU registers (when enabled/available) go here]
|
||||||
|
* mstatus
|
||||||
* [chip specific registers go here]
|
* [chip specific registers go here]
|
||||||
* pxCode
|
* pxCode
|
||||||
*/
|
*/
|
||||||
pxPortInitialiseStack:
|
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. */
|
addi a0, a0, -portWORD_SIZE /* Space for critical nesting count. */
|
||||||
store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */
|
store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */
|
||||||
|
|
||||||
|
|
@ -212,10 +206,37 @@ pxPortInitialiseStack:
|
||||||
#else
|
#else
|
||||||
addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x10-x31. */
|
addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x10-x31. */
|
||||||
#endif
|
#endif
|
||||||
store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */
|
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. */
|
|
||||||
|
addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9 + taskReturnAddress (register x1). */
|
||||||
load_x t0, xTaskReturnAddress
|
load_x t0, xTaskReturnAddress
|
||||||
store_x t0, 0(a0) /* Return address onto the stack. */
|
store_x t0, 0(a0) /* Return address onto the stack. */
|
||||||
|
|
||||||
|
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 t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */
|
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. */
|
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. */
|
beq t0, x0, 1f /* No more chip specific registers to save. */
|
||||||
|
|
@ -224,6 +245,7 @@ chip_specific_stack_frame: /* First add any chip specific registers
|
||||||
addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */
|
addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */
|
||||||
j chip_specific_stack_frame /* Until no more chip specific registers. */
|
j chip_specific_stack_frame /* Until no more chip specific registers. */
|
||||||
1:
|
1:
|
||||||
|
|
||||||
addi a0, a0, -portWORD_SIZE
|
addi a0, a0, -portWORD_SIZE
|
||||||
store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */
|
store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */
|
||||||
ret
|
ret
|
||||||
|
|
@ -237,44 +259,44 @@ xPortStartFirstTask:
|
||||||
|
|
||||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
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 x5, 1 * portWORD_SIZE( sp ) /* Initial mstatus into x5 (t0). */
|
||||||
load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */
|
addi x5, x5, 0x08 /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */
|
||||||
load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */
|
csrw mstatus, x5 /* Interrupts enabled from here! */
|
||||||
load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */
|
|
||||||
load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */
|
load_x x7, 5 * portWORD_SIZE( sp ) /* t2 */
|
||||||
load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */
|
load_x x8, 6 * portWORD_SIZE( sp ) /* s0/fp */
|
||||||
load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */
|
load_x x9, 7 * portWORD_SIZE( sp ) /* s1 */
|
||||||
load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */
|
load_x x10, 8 * portWORD_SIZE( sp ) /* a0 */
|
||||||
load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */
|
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
|
#ifndef __riscv_32e
|
||||||
load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */
|
load_x x16, 14 * portWORD_SIZE( sp ) /* a6 */
|
||||||
load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */
|
load_x x17, 15 * portWORD_SIZE( sp ) /* a7 */
|
||||||
load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */
|
load_x x18, 16 * portWORD_SIZE( sp ) /* s2 */
|
||||||
load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */
|
load_x x19, 17 * portWORD_SIZE( sp ) /* s3 */
|
||||||
load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */
|
load_x x20, 18 * portWORD_SIZE( sp ) /* s4 */
|
||||||
load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */
|
load_x x21, 19 * portWORD_SIZE( sp ) /* s5 */
|
||||||
load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */
|
load_x x22, 20 * portWORD_SIZE( sp ) /* s6 */
|
||||||
load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */
|
load_x x23, 21 * portWORD_SIZE( sp ) /* s7 */
|
||||||
load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */
|
load_x x24, 22 * portWORD_SIZE( sp ) /* s8 */
|
||||||
load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */
|
load_x x25, 23 * portWORD_SIZE( sp ) /* s9 */
|
||||||
load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */
|
load_x x26, 24 * portWORD_SIZE( sp ) /* s10 */
|
||||||
load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */
|
load_x x27, 25 * portWORD_SIZE( sp ) /* s11 */
|
||||||
load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */
|
load_x x28, 26 * portWORD_SIZE( sp ) /* t3 */
|
||||||
load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */
|
load_x x29, 27 * portWORD_SIZE( sp ) /* t4 */
|
||||||
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
load_x x30, 28 * portWORD_SIZE( sp ) /* t5 */
|
||||||
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
load_x x31, 29 * portWORD_SIZE( sp ) /* t6 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
load_x x5, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
|
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. */
|
load_x x6, pxCriticalNesting /* Load the address of xCriticalNesting into x6. */
|
||||||
store_x x5, 0( x6 ) /* Restore the critical nesting value for this task. */
|
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). */
|
load_x x5, 3 * portWORD_SIZE( sp ) /* Initial x5 (t0) value. */
|
||||||
addi x5, x5, 0x08 /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */
|
load_x x6, 4 * portWORD_SIZE( sp ) /* Initial x6 (t1) value. */
|
||||||
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. */
|
|
||||||
|
|
||||||
addi sp, sp, portCONTEXT_SIZE
|
addi sp, sp, portCONTEXT_SIZE
|
||||||
ret
|
ret
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,14 @@
|
||||||
#ifndef PORTCONTEXT_H
|
#ifndef PORTCONTEXT_H
|
||||||
#define 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
|
#if __riscv_xlen == 64
|
||||||
#define portWORD_SIZE 8
|
#define portWORD_SIZE 8
|
||||||
#define store_x sd
|
#define store_x sd
|
||||||
|
|
@ -50,65 +58,311 @@
|
||||||
* notes at the top of portASM.S file. */
|
* notes at the top of portASM.S file. */
|
||||||
#ifdef __riscv_32e
|
#ifdef __riscv_32e
|
||||||
#define portCONTEXT_SIZE ( 15 * portWORD_SIZE )
|
#define portCONTEXT_SIZE ( 15 * portWORD_SIZE )
|
||||||
#define portCRITICAL_NESTING_OFFSET 13
|
#define portCRITICAL_NESTING_OFFSET 14
|
||||||
#define portMSTATUS_OFFSET 14
|
|
||||||
#else
|
#else
|
||||||
#define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
|
#define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
|
||||||
#define portCRITICAL_NESTING_OFFSET 29
|
#define portCRITICAL_NESTING_OFFSET 30
|
||||||
#define portMSTATUS_OFFSET 30
|
|
||||||
#endif
|
#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 pxCurrentTCB
|
||||||
.extern xISRStackTop
|
.extern xISRStackTop
|
||||||
.extern xCriticalNesting
|
.extern xCriticalNesting
|
||||||
.extern pxCriticalNesting
|
.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 v24, (sp) /* Store v24-v31. */
|
||||||
|
add sp, sp, t0
|
||||||
|
vs8r.v v16, (sp) /* Store v16-v23. */
|
||||||
|
add sp, sp, t0
|
||||||
|
vs8r.v v8, (sp) /* Store v8-v15. */
|
||||||
|
add sp, sp, t0
|
||||||
|
vs8r.v v0, (sp) /* Store v0-v7. */
|
||||||
|
|
||||||
|
/* 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 v0, (sp) /* Restore v0-v7. */
|
||||||
|
add sp, sp, t0
|
||||||
|
vl8r.v v8, (sp) /* Restore v8-v15. */
|
||||||
|
add sp, sp, t0
|
||||||
|
vl8r.v v16, (sp) /* Restore v16-v23. */
|
||||||
|
add sp, sp, t0
|
||||||
|
vl8r.v v24, (sp) /* Restore v23-v31. */
|
||||||
|
add sp, sp, t0
|
||||||
|
|
||||||
|
/* Re-reserve the space for mstatus and epc. */
|
||||||
|
add sp, sp, -( 2 * portWORD_SIZE )
|
||||||
|
.endm
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
.macro portcontextSAVE_CONTEXT_INTERNAL
|
.macro portcontextSAVE_CONTEXT_INTERNAL
|
||||||
addi sp, sp, -portCONTEXT_SIZE
|
addi sp, sp, -portCONTEXT_SIZE
|
||||||
store_x x1, 1 * portWORD_SIZE( sp )
|
store_x x1, 2 * portWORD_SIZE( sp )
|
||||||
store_x x5, 2 * portWORD_SIZE( sp )
|
store_x x5, 3 * portWORD_SIZE( sp )
|
||||||
store_x x6, 3 * portWORD_SIZE( sp )
|
store_x x6, 4 * portWORD_SIZE( sp )
|
||||||
store_x x7, 4 * portWORD_SIZE( sp )
|
store_x x7, 5 * portWORD_SIZE( sp )
|
||||||
store_x x8, 5 * portWORD_SIZE( sp )
|
store_x x8, 6 * portWORD_SIZE( sp )
|
||||||
store_x x9, 6 * portWORD_SIZE( sp )
|
store_x x9, 7 * portWORD_SIZE( sp )
|
||||||
store_x x10, 7 * portWORD_SIZE( sp )
|
store_x x10, 8 * portWORD_SIZE( sp )
|
||||||
store_x x11, 8 * portWORD_SIZE( sp )
|
store_x x11, 9 * portWORD_SIZE( sp )
|
||||||
store_x x12, 9 * portWORD_SIZE( sp )
|
store_x x12, 10 * portWORD_SIZE( sp )
|
||||||
store_x x13, 10 * portWORD_SIZE( sp )
|
store_x x13, 11 * portWORD_SIZE( sp )
|
||||||
store_x x14, 11 * portWORD_SIZE( sp )
|
store_x x14, 12 * portWORD_SIZE( sp )
|
||||||
store_x x15, 12 * portWORD_SIZE( sp )
|
store_x x15, 13 * portWORD_SIZE( sp )
|
||||||
#ifndef __riscv_32e
|
#ifndef __riscv_32e
|
||||||
store_x x16, 13 * portWORD_SIZE( sp )
|
store_x x16, 14 * portWORD_SIZE( sp )
|
||||||
store_x x17, 14 * portWORD_SIZE( sp )
|
store_x x17, 15 * portWORD_SIZE( sp )
|
||||||
store_x x18, 15 * portWORD_SIZE( sp )
|
store_x x18, 16 * portWORD_SIZE( sp )
|
||||||
store_x x19, 16 * portWORD_SIZE( sp )
|
store_x x19, 17 * portWORD_SIZE( sp )
|
||||||
store_x x20, 17 * portWORD_SIZE( sp )
|
store_x x20, 18 * portWORD_SIZE( sp )
|
||||||
store_x x21, 18 * portWORD_SIZE( sp )
|
store_x x21, 19 * portWORD_SIZE( sp )
|
||||||
store_x x22, 19 * portWORD_SIZE( sp )
|
store_x x22, 20 * portWORD_SIZE( sp )
|
||||||
store_x x23, 20 * portWORD_SIZE( sp )
|
store_x x23, 21 * portWORD_SIZE( sp )
|
||||||
store_x x24, 21 * portWORD_SIZE( sp )
|
store_x x24, 22 * portWORD_SIZE( sp )
|
||||||
store_x x25, 22 * portWORD_SIZE( sp )
|
store_x x25, 23 * portWORD_SIZE( sp )
|
||||||
store_x x26, 23 * portWORD_SIZE( sp )
|
store_x x26, 24 * portWORD_SIZE( sp )
|
||||||
store_x x27, 24 * portWORD_SIZE( sp )
|
store_x x27, 25 * portWORD_SIZE( sp )
|
||||||
store_x x28, 25 * portWORD_SIZE( sp )
|
store_x x28, 26 * portWORD_SIZE( sp )
|
||||||
store_x x29, 26 * portWORD_SIZE( sp )
|
store_x x29, 27 * portWORD_SIZE( sp )
|
||||||
store_x x30, 27 * portWORD_SIZE( sp )
|
store_x x30, 28 * portWORD_SIZE( sp )
|
||||||
store_x x31, 28 * portWORD_SIZE( sp )
|
store_x x31, 29 * portWORD_SIZE( sp )
|
||||||
#endif /* ifndef __riscv_32e */
|
#endif /* ifndef __riscv_32e */
|
||||||
|
|
||||||
load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */
|
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. */
|
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. */
|
portcontexSAVE_FPU_CONTEXT
|
||||||
store_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp )
|
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 VPU registers. */
|
||||||
|
|
||||||
|
portcontexSAVE_VPU_CONTEXT
|
||||||
|
2:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
csrr t0, mstatus
|
||||||
|
store_x t0, 1 * portWORD_SIZE( sp )
|
||||||
|
|
||||||
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||||
|
|
||||||
|
#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. */
|
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||||
store_x sp, 0 ( t0 ) /* Write sp to first TCB member. */
|
store_x sp, 0 ( t0 ) /* Write sp to first TCB member. */
|
||||||
|
|
||||||
|
|
@ -145,43 +399,65 @@ csrw mepc, t0
|
||||||
/* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
/* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||||
portasmRESTORE_ADDITIONAL_REGISTERS
|
portasmRESTORE_ADDITIONAL_REGISTERS
|
||||||
|
|
||||||
/* Load mstatus with the interrupt enable bits used by the task. */
|
/* Restore mstatus register. It is important to use t3 (and not t0) here as t3
|
||||||
load_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp )
|
* is not clobbered by portcontextRESTORE_VPU_CONTEXT and
|
||||||
csrw mstatus, t0 /* Required for MPIE bit. */
|
* portcontextRESTORE_FPU_CONTEXT. */
|
||||||
|
load_x t3, 1 * portWORD_SIZE( sp )
|
||||||
|
csrw mstatus, t3
|
||||||
|
|
||||||
|
#if( configENABLE_VPU == 1 )
|
||||||
|
srl t1, t3, 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 )
|
||||||
|
srl t1, t3, 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 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. */
|
load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */
|
||||||
store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */
|
store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */
|
||||||
|
|
||||||
load_x x1, 1 * portWORD_SIZE( sp )
|
load_x x1, 2 * portWORD_SIZE( sp )
|
||||||
load_x x5, 2 * portWORD_SIZE( sp )
|
load_x x5, 3 * portWORD_SIZE( sp )
|
||||||
load_x x6, 3 * portWORD_SIZE( sp )
|
load_x x6, 4 * portWORD_SIZE( sp )
|
||||||
load_x x7, 4 * portWORD_SIZE( sp )
|
load_x x7, 5 * portWORD_SIZE( sp )
|
||||||
load_x x8, 5 * portWORD_SIZE( sp )
|
load_x x8, 6 * portWORD_SIZE( sp )
|
||||||
load_x x9, 6 * portWORD_SIZE( sp )
|
load_x x9, 7 * portWORD_SIZE( sp )
|
||||||
load_x x10, 7 * portWORD_SIZE( sp )
|
load_x x10, 8 * portWORD_SIZE( sp )
|
||||||
load_x x11, 8 * portWORD_SIZE( sp )
|
load_x x11, 9 * portWORD_SIZE( sp )
|
||||||
load_x x12, 9 * portWORD_SIZE( sp )
|
load_x x12, 10 * portWORD_SIZE( sp )
|
||||||
load_x x13, 10 * portWORD_SIZE( sp )
|
load_x x13, 11 * portWORD_SIZE( sp )
|
||||||
load_x x14, 11 * portWORD_SIZE( sp )
|
load_x x14, 12 * portWORD_SIZE( sp )
|
||||||
load_x x15, 12 * portWORD_SIZE( sp )
|
load_x x15, 13 * portWORD_SIZE( sp )
|
||||||
#ifndef __riscv_32e
|
#ifndef __riscv_32e
|
||||||
load_x x16, 13 * portWORD_SIZE( sp )
|
load_x x16, 14 * portWORD_SIZE( sp )
|
||||||
load_x x17, 14 * portWORD_SIZE( sp )
|
load_x x17, 15 * portWORD_SIZE( sp )
|
||||||
load_x x18, 15 * portWORD_SIZE( sp )
|
load_x x18, 16 * portWORD_SIZE( sp )
|
||||||
load_x x19, 16 * portWORD_SIZE( sp )
|
load_x x19, 17 * portWORD_SIZE( sp )
|
||||||
load_x x20, 17 * portWORD_SIZE( sp )
|
load_x x20, 18 * portWORD_SIZE( sp )
|
||||||
load_x x21, 18 * portWORD_SIZE( sp )
|
load_x x21, 19 * portWORD_SIZE( sp )
|
||||||
load_x x22, 19 * portWORD_SIZE( sp )
|
load_x x22, 20 * portWORD_SIZE( sp )
|
||||||
load_x x23, 20 * portWORD_SIZE( sp )
|
load_x x23, 21 * portWORD_SIZE( sp )
|
||||||
load_x x24, 21 * portWORD_SIZE( sp )
|
load_x x24, 22 * portWORD_SIZE( sp )
|
||||||
load_x x25, 22 * portWORD_SIZE( sp )
|
load_x x25, 23 * portWORD_SIZE( sp )
|
||||||
load_x x26, 23 * portWORD_SIZE( sp )
|
load_x x26, 24 * portWORD_SIZE( sp )
|
||||||
load_x x27, 24 * portWORD_SIZE( sp )
|
load_x x27, 25 * portWORD_SIZE( sp )
|
||||||
load_x x28, 25 * portWORD_SIZE( sp )
|
load_x x28, 26 * portWORD_SIZE( sp )
|
||||||
load_x x29, 26 * portWORD_SIZE( sp )
|
load_x x29, 27 * portWORD_SIZE( sp )
|
||||||
load_x x30, 27 * portWORD_SIZE( sp )
|
load_x x30, 28 * portWORD_SIZE( sp )
|
||||||
load_x x31, 28 * portWORD_SIZE( sp )
|
load_x x31, 29 * portWORD_SIZE( sp )
|
||||||
#endif /* ifndef __riscv_32e */
|
#endif /* ifndef __riscv_32e */
|
||||||
addi sp, sp, portCONTEXT_SIZE
|
addi sp, sp, portCONTEXT_SIZE
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue