Compare commits
24 Commits
collab-rus
...
collab-mes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5e7142b3d | ||
|
|
955b1f677b | ||
|
|
dab117c85e | ||
|
|
aeeb2053c6 | ||
|
|
1b44e607a8 | ||
|
|
c1f5ae30c6 | ||
|
|
bbd0498803 | ||
|
|
85a856d79a | ||
|
|
ef43b94495 | ||
|
|
62f08da47b | ||
|
|
81dbc697f4 | ||
|
|
dfdce2c122 | ||
|
|
6724345372 | ||
|
|
0bb34284d9 | ||
|
|
55175d63e4 | ||
|
|
d7b4497054 | ||
|
|
9d61afa758 | ||
|
|
cddbafe374 | ||
|
|
71b29f4796 | ||
|
|
563aa9be92 | ||
|
|
6874a4a719 | ||
|
|
380bd5483e | ||
|
|
988ad5b0c2 | ||
|
|
470c0d13a0 |
@@ -39,7 +39,6 @@ ForEachMacros:
|
||||
- 'FOR_EACH_IDX'
|
||||
- 'FOR_EACH_IDX_FIXED_ARG'
|
||||
- 'FOR_EACH_NONEMPTY_TERM'
|
||||
- 'FOR_EACH_FIXED_ARG_NONEMPTY_TERM'
|
||||
- 'RB_FOR_EACH'
|
||||
- 'RB_FOR_EACH_CONTAINER'
|
||||
- 'SYS_DLIST_FOR_EACH_CONTAINER'
|
||||
@@ -69,16 +68,8 @@ ForEachMacros:
|
||||
- 'Z_GENLIST_FOR_EACH_NODE'
|
||||
- 'Z_GENLIST_FOR_EACH_NODE_SAFE'
|
||||
- 'STRUCT_SECTION_FOREACH'
|
||||
- 'STRUCT_SECTION_FOREACH_ALTERNATE'
|
||||
- 'TYPE_SECTION_FOREACH'
|
||||
- 'K_SPINLOCK'
|
||||
- 'COAP_RESOURCE_FOREACH'
|
||||
- 'COAP_SERVICE_FOREACH'
|
||||
- 'COAP_SERVICE_FOREACH_RESOURCE'
|
||||
- 'HTTP_RESOURCE_FOREACH'
|
||||
- 'HTTP_SERVER_CONTENT_TYPE_FOREACH'
|
||||
- 'HTTP_SERVICE_FOREACH'
|
||||
- 'HTTP_SERVICE_FOREACH_RESOURCE'
|
||||
IfMacros:
|
||||
- 'CHECKIF'
|
||||
# Disabled for now, see bug https://github.com/zephyrproject-rtos/zephyr/issues/48520
|
||||
@@ -93,10 +84,8 @@ IncludeCategories:
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IndentCaseLabels: false
|
||||
IndentGotoLabels: false
|
||||
IndentWidth: 8
|
||||
InsertBraces: true
|
||||
SpaceBeforeInheritanceColon: False
|
||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||
SortIncludes: Never
|
||||
UseTab: ForContinuationAndIndentation
|
||||
|
||||
18
.github/ISSUE_TEMPLATE/001_bug_report.md
vendored
18
.github/ISSUE_TEMPLATE/001_bug_report.md
vendored
@@ -6,8 +6,8 @@ labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
<!--
|
||||
**Notes**
|
||||
|
||||
**Notes (delete this)**
|
||||
Github Discussions (https://github.com/zephyrproject-rtos/zephyr/discussions)
|
||||
are available to first verify that the issue is a genuine Zephyr bug and not a
|
||||
consequence of Zephyr services misuse.
|
||||
@@ -16,10 +16,8 @@ This issue list is only for bugs in the main Zephyr code base
|
||||
(https://github.com/zephyrproject-rtos/zephyr/). If the bug is for a project
|
||||
fork (such as NCS) specific feature, please open an issue in the fork project
|
||||
instead.
|
||||
-->
|
||||
|
||||
**Describe the bug**
|
||||
<!--
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
Please also mention any information which could help others to understand
|
||||
@@ -29,43 +27,31 @@ the problem you're facing:
|
||||
- Is this a regression? If yes, have you been able to "git bisect" it to a
|
||||
specific commit?
|
||||
- ...
|
||||
-->
|
||||
|
||||
**To Reproduce**
|
||||
<!--
|
||||
Steps to reproduce the behavior:
|
||||
1. mkdir build; cd build
|
||||
2. cmake -DBOARD=board\_xyz
|
||||
3. make
|
||||
4. See error
|
||||
-->
|
||||
|
||||
**Expected behavior**
|
||||
<!--
|
||||
A clear and concise description of what you expected to happen.
|
||||
-->
|
||||
|
||||
**Impact**
|
||||
<!--
|
||||
What impact does this issue have on your progress (e.g., annoyance, showstopper)
|
||||
-->
|
||||
|
||||
**Logs and console output**
|
||||
<!--
|
||||
If applicable, add console logs or other types of debug information
|
||||
e.g Wireshark capture or Logic analyzer capture (upload in zip archive).
|
||||
copy-and-paste text and put a code fence (\`\`\`) before and after, to help
|
||||
explain the issue. (if unable to obtain text log, add a screenshot)
|
||||
-->
|
||||
|
||||
**Environment (please complete the following information):**
|
||||
|
||||
- OS: (e.g. Linux, MacOS, Windows)
|
||||
- Toolchain (e.g Zephyr SDK, ...)
|
||||
- Commit SHA or Version used
|
||||
|
||||
**Additional context**
|
||||
<!--
|
||||
Add any other context that could be relevant to your issue, such as pin setting,
|
||||
target configuration, ...
|
||||
-->
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/002_enhancement.md
vendored
8
.github/ISSUE_TEMPLATE/002_enhancement.md
vendored
@@ -8,21 +8,13 @@ assignees: ''
|
||||
---
|
||||
|
||||
**Is your enhancement proposal related to a problem? Please describe.**
|
||||
<!--
|
||||
A clear and concise description of what the problem is.
|
||||
-->
|
||||
|
||||
**Describe the solution you'd like**
|
||||
<!--
|
||||
A clear and concise description of what you want to happen.
|
||||
-->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
<!--
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
-->
|
||||
|
||||
**Additional context**
|
||||
<!--
|
||||
Add any other context or graphics (drag-and-drop an image) about the feature request here.
|
||||
-->
|
||||
|
||||
23
.github/ISSUE_TEMPLATE/003_rfc-proposal.md
vendored
23
.github/ISSUE_TEMPLATE/003_rfc-proposal.md
vendored
@@ -9,52 +9,43 @@ assignees: ''
|
||||
|
||||
## Introduction
|
||||
|
||||
<!--
|
||||
This section targets end users, TSC members, maintainers and anyone else that might
|
||||
need a quick explanation of your proposed change.
|
||||
-->
|
||||
|
||||
### Problem description
|
||||
<!--
|
||||
|
||||
Why do we want this change and what problem are we trying to address?
|
||||
-->
|
||||
|
||||
### Proposed change
|
||||
<!--
|
||||
|
||||
A brief summary of the proposed change - the 10,000 ft view on what it will
|
||||
change once this change is implemented.
|
||||
-->
|
||||
|
||||
## Detailed RFC
|
||||
<!--
|
||||
|
||||
In this section of the document the target audience is the dev team. Upon
|
||||
reading this section each engineer should have a rather clear picture of what
|
||||
needs to be done in order to implement the described feature.
|
||||
-->
|
||||
|
||||
### Proposed change (Detailed)
|
||||
<!--
|
||||
|
||||
This section is freeform - you should describe your change in as much detail
|
||||
as possible. Please also ensure to include any context or background info here.
|
||||
For example, do we have existing components which can be reused or altered.
|
||||
|
||||
By reading this section, each team member should be able to know what exactly
|
||||
you're planning to change and how.
|
||||
-->
|
||||
|
||||
### Dependencies
|
||||
<!--
|
||||
|
||||
Highlight how the change may affect the rest of the project (new components,
|
||||
modifications in other areas), or other teams/projects.
|
||||
-->
|
||||
|
||||
### Concerns and Unresolved Questions
|
||||
<!--
|
||||
|
||||
List any concerns, unknowns, and generally unresolved questions etc.
|
||||
-->
|
||||
|
||||
## Alternatives
|
||||
<!--
|
||||
|
||||
List any alternatives considered, and the reasons for choosing this option
|
||||
over them.
|
||||
-->
|
||||
|
||||
@@ -8,21 +8,13 @@ assignees: ''
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
<!--
|
||||
A clear and concise description of what the problem is.
|
||||
-->
|
||||
|
||||
**Describe the solution you'd like**
|
||||
<!--
|
||||
A clear and concise description of what you want to happen.
|
||||
-->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
<!--
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
-->
|
||||
|
||||
**Additional context**
|
||||
<!--
|
||||
Add any other context or graphics (drag-and-drop an image) about the feature request here.
|
||||
-->
|
||||
|
||||
6
.github/SECURITY.md
vendored
6
.github/SECURITY.md
vendored
@@ -11,9 +11,9 @@ updates:
|
||||
At this time, with the latest release of v3.6, the supported
|
||||
versions are:
|
||||
|
||||
- v3.7: Current LTS
|
||||
- v3.6: Prior release
|
||||
- v2.7: Prior LTS
|
||||
- v2.7: Current LTS
|
||||
- v3.5: Prior release
|
||||
- v3.6: Current release
|
||||
|
||||
## Reporting process
|
||||
|
||||
|
||||
44
.github/workflows/compliance.yml
vendored
44
.github/workflows/compliance.yml
vendored
@@ -1,12 +1,6 @@
|
||||
name: Compliance Checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
check_compliance:
|
||||
@@ -38,7 +32,7 @@ jobs:
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install wheel
|
||||
pip3 install python-magic lxml junitparser gitlint pylint pykwalify yamllint clang-format unidiff
|
||||
pip3 install python-magic lxml junitparser gitlint pylint pykwalify yamllint
|
||||
pip3 install west
|
||||
|
||||
- name: west setup
|
||||
@@ -58,14 +52,6 @@ jobs:
|
||||
west config manifest.group-filter -- +ci,-optional
|
||||
west update -o=--depth=1 -n 2>&1 1> west.update.log || west update -o=--depth=1 -n 2>&1 1> west.update2.log
|
||||
|
||||
- name: Check for PR description
|
||||
if: ${{ github.event.pull_request.body == '' }}
|
||||
continue-on-error: true
|
||||
id: pr_description
|
||||
run: |
|
||||
echo "Pull request description cannot be empty."
|
||||
exit 1
|
||||
|
||||
- name: Run Compliance Tests
|
||||
continue-on-error: true
|
||||
id: compliance
|
||||
@@ -94,33 +80,19 @@ jobs:
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
warns=("ClangFormat")
|
||||
files=($(./scripts/ci/check_compliance.py -l))
|
||||
|
||||
for file in "${files[@]}"; do
|
||||
f="${file}.txt"
|
||||
if [[ -s $f ]]; then
|
||||
results=$(cat $f)
|
||||
results="${results//'%'/'%25'}"
|
||||
results="${results//$'\n'/'%0A'}"
|
||||
results="${results//$'\r'/'%0D'}"
|
||||
|
||||
if [[ "${warns[@]}" =~ "${file}" ]]; then
|
||||
echo "::warning file=${f}::$results"
|
||||
else
|
||||
echo "::error file=${f}::$results"
|
||||
exit=1
|
||||
fi
|
||||
errors=$(cat $f)
|
||||
errors="${errors//'%'/'%25'}"
|
||||
errors="${errors//$'\n'/'%0A'}"
|
||||
errors="${errors//$'\r'/'%0D'}"
|
||||
echo "::error file=${f}::$errors"
|
||||
exit=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${exit}" == "1" ]; then
|
||||
echo "Compliance error, check for error messages in the \"Run Compliance Tests\" step"
|
||||
echo "You can run this step locally with the ./scripts/ci/check_compliance.py script."
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [ "${{ steps.pr_description.outcome }}" == "failure" ]; then
|
||||
echo "PR description cannot be empty"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
4
.github/workflows/devicetree_checks.yml
vendored
4
.github/workflows/devicetree_checks.yml
vendored
@@ -27,9 +27,9 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.10', '3.11', '3.12']
|
||||
os: [ubuntu-22.04, macos-14, windows-2022]
|
||||
os: [ubuntu-22.04, macos-11, windows-2022]
|
||||
exclude:
|
||||
- os: macos-14
|
||||
- os: macos-11
|
||||
python-version: 3.6
|
||||
- os: windows-2022
|
||||
python-version: 3.6
|
||||
|
||||
8
.github/workflows/doc-build.yml
vendored
8
.github/workflows/doc-build.yml
vendored
@@ -17,7 +17,7 @@ env:
|
||||
# The latest CMake available directly with apt is 3.18, but we need >=3.20
|
||||
# so we fetch that through pip.
|
||||
CMAKE_VERSION: 3.20.5
|
||||
DOXYGEN_VERSION: 1.12.0
|
||||
DOXYGEN_VERSION: 1.9.6
|
||||
# Job count is set to 2 less than the vCPU count of 16 because the total available RAM is 32GiB
|
||||
# and each sphinx-build process may use more than 2GiB of RAM.
|
||||
JOB_COUNT: 14
|
||||
@@ -149,9 +149,9 @@ jobs:
|
||||
|
||||
- name: compress-docs
|
||||
run: |
|
||||
tar --use-compress-program="xz -T0" -cf html-output.tar.xz --directory=doc/_build html
|
||||
tar --use-compress-program="xz -T0" -cf api-output.tar.xz --directory=doc/_build html/doxygen/html
|
||||
tar --use-compress-program="xz -T0" -cf api-coverage.tar.xz coverage-report
|
||||
tar cfJ html-output.tar.xz --directory=doc/_build html
|
||||
tar cfJ api-output.tar.xz --directory=doc/_build html/doxygen/html
|
||||
tar cfJ api-coverage.tar.xz coverage-report
|
||||
|
||||
- name: upload-build
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-24.04, macos-13, macos-14, windows-2022]
|
||||
os: [ubuntu-22.04, macos-12, macos-14, windows-2022]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
3
.github/workflows/manifest.yml
vendored
3
.github/workflows/manifest.yml
vendored
@@ -26,13 +26,12 @@ jobs:
|
||||
west init -l . || true
|
||||
|
||||
- name: Manifest
|
||||
uses: zephyrproject-rtos/action-manifest@v1.3.1
|
||||
uses: zephyrproject-rtos/action-manifest@v1.2.2
|
||||
with:
|
||||
github-token: ${{ secrets.ZB_GITHUB_TOKEN }}
|
||||
manifest-path: 'west.yml'
|
||||
checkout-path: 'zephyrproject/zephyr'
|
||||
use-tree-checkout: 'true'
|
||||
check-impostor-commits: 'true'
|
||||
label-prefix: 'manifest-'
|
||||
verbosity-level: '1'
|
||||
labels: 'manifest'
|
||||
|
||||
61
.github/workflows/scorecards.yml
vendored
61
.github/workflows/scorecards.yml
vendored
@@ -1,61 +0,0 @@
|
||||
# This workflow uses actions that are not certified by GitHub. They are provided
|
||||
# by a third-party and are governed by separate terms of service, privacy
|
||||
# policy, and support documentation.
|
||||
|
||||
name: Scorecards supply-chain security
|
||||
on:
|
||||
# For Branch-Protection check. Only the default branch is supported. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||
branch_protection_rule:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: '43 7 * * 6'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed for Code scanning upload
|
||||
security-events: write
|
||||
# Needed for GitHub OIDC token if publish_results is true
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# Publish results to OpenSSF REST API for easy access by consumers.
|
||||
# - Allows the repository to include the Scorecard badge.
|
||||
# - See https://github.com/ossf/scorecard-action#publishing-results.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable
|
||||
# uploads of run results in SARIF format to the repository Actions tab.
|
||||
# https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard (optional).
|
||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
7
.github/workflows/twister.yaml
vendored
7
.github/workflows/twister.yaml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on:
|
||||
group: zephyr-runner-v2-linux-x64-4xlarge
|
||||
container:
|
||||
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.14.20240823
|
||||
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601
|
||||
options: '--entrypoint /bin/bash'
|
||||
outputs:
|
||||
subset: ${{ steps.output-services.outputs.subset }}
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
needs: twister-build-prep
|
||||
if: needs.twister-build-prep.outputs.size != 0
|
||||
container:
|
||||
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.14.20240823
|
||||
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.26.13.20240601
|
||||
options: '--entrypoint /bin/bash'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -188,7 +188,6 @@ jobs:
|
||||
git log --pretty=oneline | head -n 10
|
||||
fi
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
|
||||
west init -l . || true
|
||||
west config manifest.group-filter -- +ci,+optional
|
||||
@@ -202,8 +201,6 @@ jobs:
|
||||
run: |
|
||||
cmake --version
|
||||
gcc --version
|
||||
cargo --version
|
||||
rustup target list --installed
|
||||
ls -la
|
||||
echo "github.ref: ${{ github.ref }}"
|
||||
echo "github.base_ref: ${{ github.base_ref }}"
|
||||
|
||||
2
.github/workflows/twister_tests_blackbox.yml
vendored
2
.github/workflows/twister_tests_blackbox.yml
vendored
@@ -43,8 +43,6 @@ jobs:
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
west init -l . || true
|
||||
# we do not depend on any hals, tools or bootloader, save some time and space...
|
||||
west config manifest.group-filter -- -hal,-tools,-bootloader
|
||||
west config --global update.narrow true
|
||||
west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || west update --path-cache /github/cache/zephyrproject 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/cache/zephyrproject)
|
||||
west forall -c 'git reset --hard HEAD'
|
||||
|
||||
4
.github/workflows/west_cmds.yml
vendored
4
.github/workflows/west_cmds.yml
vendored
@@ -30,9 +30,9 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.10', '3.11', '3.12']
|
||||
os: [ubuntu-22.04, macos-14, windows-2022]
|
||||
os: [ubuntu-22.04, macos-11, windows-2022]
|
||||
exclude:
|
||||
- os: macos-14
|
||||
- os: macos-11
|
||||
python-version: 3.6
|
||||
- os: windows-2022
|
||||
python-version: 3.6
|
||||
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -59,18 +59,6 @@ venv
|
||||
.clangd
|
||||
new.info
|
||||
|
||||
# Cargo drops lock files in projects to capture resolved dependencies.
|
||||
# We don't want to record these.
|
||||
Cargo.lock
|
||||
|
||||
# Cargo encourages a .cargo/config.toml file to symlink to a generated
|
||||
# file. Don't save these.
|
||||
.cargo/
|
||||
|
||||
# Normal west builds will place the Rust target directory under the build directory. However,
|
||||
# sometimes IDEs and such will litter these target directories as well.
|
||||
target/
|
||||
|
||||
# CI output
|
||||
compliance.xml
|
||||
_error.types
|
||||
@@ -88,7 +76,6 @@ tags
|
||||
BinaryFiles.txt
|
||||
BoardYml.txt
|
||||
Checkpatch.txt
|
||||
ClangFormat.txt
|
||||
DevicetreeBindings.txt
|
||||
GitDiffCheck.txt
|
||||
Gitlint.txt
|
||||
|
||||
1
.mailmap
1
.mailmap
@@ -61,7 +61,6 @@ Lixin Guo <lixinx.guo@intel.com>
|
||||
Łukasz Mazur <lukasz.mazur@hidglobal.com>
|
||||
Manuel Argüelles <manuel.arguelles@nxp.com>
|
||||
Manuel Argüelles <manuel.arguelles@nxp.com> <manuel.arguelles@coredumplabs.com>
|
||||
Manuel Argüelles <manuel.arguelles@nxp.com> <marguelles.dev@gmail.com>
|
||||
Marc Herbert <marc.herbert@intel.com> <46978960+marc-hb@users.noreply.github.com>
|
||||
Marin Jurjević <marin.jurjevic@hotmail.com>
|
||||
Mariusz Ryndzionek <mariusz.ryndzionek@firmwave.com>
|
||||
|
||||
@@ -1613,14 +1613,11 @@ endif()
|
||||
|
||||
if(CONFIG_BUILD_OUTPUT_ADJUST_LMA)
|
||||
math(EXPR adjustment "${CONFIG_BUILD_OUTPUT_ADJUST_LMA}" OUTPUT_FORMAT DECIMAL)
|
||||
set(args_adjustment ${CONFIG_BUILD_OUTPUT_ADJUST_LMA_SECTIONS})
|
||||
list(TRANSFORM args_adjustment PREPEND $<TARGET_PROPERTY:bintools,elfconvert_flag_lma_adjust>)
|
||||
list(TRANSFORM args_adjustment APPEND +${adjustment})
|
||||
list(APPEND
|
||||
post_build_commands
|
||||
COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command>
|
||||
$<TARGET_PROPERTY:bintools,elfconvert_flag_final>
|
||||
${args_adjustment}
|
||||
$<TARGET_PROPERTY:bintools,elfconvert_flag_lma_adjust>${adjustment}
|
||||
$<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME}
|
||||
$<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_ELF_NAME}
|
||||
)
|
||||
@@ -1901,6 +1898,7 @@ if (CONFIG_LLEXT AND CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID)
|
||||
${ZEPHYR_BASE}/scripts/build/llext_prepare_exptab.py
|
||||
--elf-file ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}
|
||||
--slid-listing ${PROJECT_BINARY_DIR}/slid_listing.txt
|
||||
-vvv
|
||||
)
|
||||
|
||||
endif()
|
||||
@@ -1991,39 +1989,22 @@ elseif(CONFIG_LOG_MIPI_SYST_USE_CATALOG)
|
||||
endif()
|
||||
|
||||
if(LOG_DICT_DB_NAME_ARG)
|
||||
set(log_dict_gen_command
|
||||
if (NOT CONFIG_LOG_DICTIONARY_DB_TARGET)
|
||||
set(LOG_DICT_DB_ALL_TARGET ALL)
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${LOG_DICT_DB_NAME}
|
||||
COMMAND
|
||||
${PYTHON_EXECUTABLE}
|
||||
${ZEPHYR_BASE}/scripts/logging/dictionary/database_gen.py
|
||||
${KERNEL_ELF_NAME}
|
||||
${LOG_DICT_DB_NAME_ARG}=${LOG_DICT_DB_NAME}
|
||||
--build-header ${PROJECT_BINARY_DIR}/include/generated/zephyr/version.h
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
COMMENT "Generating logging dictionary database: ${LOG_DICT_DB_NAME}"
|
||||
DEPENDS ${logical_target_for_zephyr_elf}
|
||||
)
|
||||
|
||||
if (NOT CONFIG_LOG_DICTIONARY_DB_TARGET)
|
||||
# If not using a separate target for generating logging dictionary
|
||||
# database, add the generation to post build command to make sure
|
||||
# the database is actually being generated.
|
||||
list(APPEND
|
||||
post_build_commands
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Generating logging dictionary database: ${LOG_DICT_DB_NAME}"
|
||||
COMMAND ${log_dict_gen_command}
|
||||
)
|
||||
list(APPEND
|
||||
post_build_byproducts
|
||||
${LOG_DICT_DB_NAME}
|
||||
)
|
||||
else()
|
||||
# Seprate build target for generating logging dictionary database.
|
||||
# This needs to be explicitly called/used to generate the database.
|
||||
add_custom_command(
|
||||
OUTPUT ${LOG_DICT_DB_NAME}
|
||||
COMMAND ${log_dict_gen_command}
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
COMMENT "Generating logging dictionary database: ${LOG_DICT_DB_NAME}"
|
||||
DEPENDS ${logical_target_for_zephyr_elf}
|
||||
)
|
||||
add_custom_target(log_dict_db_gen DEPENDS ${LOG_DICT_DB_NAME})
|
||||
endif()
|
||||
add_custom_target(log_dict_db_gen ${LOG_DICT_DB_ALL_TARGET} DEPENDS ${LOG_DICT_DB_NAME})
|
||||
endif()
|
||||
|
||||
# Add post_build_commands to post-process the final .elf file produced by
|
||||
@@ -2136,15 +2117,12 @@ endif()
|
||||
set(llext_edk_file ${PROJECT_BINARY_DIR}/${CONFIG_LLEXT_EDK_NAME}.tar.xz)
|
||||
|
||||
# TODO maybe generate flags for C CXX ASM
|
||||
zephyr_get_compile_definitions_for_lang(C zephyr_defs)
|
||||
zephyr_get_compile_options_for_lang(C zephyr_flags)
|
||||
|
||||
# Filter out non LLEXT and LLEXT_EDK flags - and add required ones
|
||||
llext_filter_zephyr_flags(LLEXT_REMOVE_FLAGS ${zephyr_flags} llext_filt_flags)
|
||||
llext_filter_zephyr_flags(LLEXT_EDK_REMOVE_FLAGS ${llext_filt_flags} llext_filt_flags)
|
||||
llext_filter_zephyr_flags(LLEXT_REMOVE_FLAGS ${zephyr_flags} llext_edk_cflags)
|
||||
llext_filter_zephyr_flags(LLEXT_EDK_REMOVE_FLAGS ${llext_edk_cflags} llext_edk_cflags)
|
||||
|
||||
set(llext_edk_cflags ${zephyr_defs} -DLL_EXTENSION_BUILD)
|
||||
list(APPEND llext_edk_cflags ${llext_filt_flags})
|
||||
list(APPEND llext_edk_cflags ${LLEXT_APPEND_FLAGS})
|
||||
list(APPEND llext_edk_cflags ${LLEXT_EDK_APPEND_FLAGS})
|
||||
|
||||
@@ -2168,7 +2146,7 @@ add_custom_command(
|
||||
-DAPPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR}
|
||||
-DINTERFACE_INCLUDE_DIRECTORIES="$<TARGET_PROPERTY:zephyr_interface,INTERFACE_INCLUDE_DIRECTORIES>"
|
||||
-Dllext_edk_file=${llext_edk_file}
|
||||
-Dllext_edk_cflags="${llext_edk_cflags}"
|
||||
-Dllext_cflags="${llext_edk_cflags}"
|
||||
-Dllext_edk_name=${CONFIG_LLEXT_EDK_NAME}
|
||||
-DWEST_TOPDIR=${WEST_TOPDIR}
|
||||
-DZEPHYR_BASE=${ZEPHYR_BASE}
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
/soc/riscv/riscv-privileged/gd32vf103/ @soburi
|
||||
/soc/starfive/jh71xx/ @pfarwsi
|
||||
/soc/riscv/riscv-privileged/niosv/ @sweeaun
|
||||
/boards/adafruit/feather_nrf52840/ @jacobw
|
||||
/boards/ene/ @ene-steven
|
||||
/boards/arm/96b_argonkey/ @avisconti
|
||||
/boards/arm/96b_avenger96/ @Mani-Sadhasivam
|
||||
@@ -188,7 +187,6 @@
|
||||
/drivers/dai/intel/ssp/ @kv2019i @marcinszkudlinski @abonislawski
|
||||
/drivers/dai/intel/dmic/ @marcinszkudlinski @abonislawski
|
||||
/drivers/dai/intel/alh/ @abonislawski
|
||||
/drivers/dma/dma_dw_axi.c @pbalsundar
|
||||
/drivers/dma/*dw* @tbursztyka
|
||||
/drivers/dma/*dw_common* @abonislawski
|
||||
/drivers/dma/*sam0* @Sizurka
|
||||
@@ -328,6 +326,7 @@
|
||||
/drivers/serial/uart_altera.c @gohshunjing
|
||||
/drivers/serial/*ns16550* @dcpleung @nashif @gdengi
|
||||
/drivers/serial/*nrfx* @anangl
|
||||
/drivers/serial/uart_liteuart.c @mateusz-holenko @kgugala @pgielda
|
||||
/drivers/serial/Kconfig.mcux_iuart @Mani-Sadhasivam
|
||||
/drivers/serial/uart_mcux_iuart.c @Mani-Sadhasivam
|
||||
/drivers/serial/Kconfig.rtt @carlescufi @pkral78
|
||||
@@ -368,6 +367,7 @@
|
||||
/drivers/timer/*rcar_cmt* @aaillet
|
||||
/drivers/timer/*esp32_sys* @uLipe
|
||||
/drivers/timer/*sam0_rtc* @bendiscz
|
||||
/drivers/timer/*arcv2* @ruuddw
|
||||
/drivers/timer/*xtensa* @dcpleung
|
||||
/drivers/timer/*rv32m1_lptmr* @mbolivar
|
||||
/drivers/timer/*nrf_rtc* @anangl
|
||||
@@ -395,6 +395,7 @@
|
||||
/drivers/wifi/eswifi/ @loicpoulain @nandojve
|
||||
/drivers/wifi/winc1500/ @kludentwo
|
||||
/drivers/virtualization/ @tbursztyka
|
||||
/dts/arc/ @abrodkin @ruuddw @iriszzw @evgeniy-paltsev
|
||||
/dts/arm/acsip/ @NorthernDean
|
||||
/dts/arm/aspeed/ @aspeeddylan
|
||||
/dts/arm/atmel/ @galak @nandojve
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# Constant variables to be used across Kconfig options
|
||||
|
||||
# Copyright (c) 2024 basalte bv
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
INT8_MIN := -128
|
||||
INT16_MIN := -32768
|
||||
INT32_MIN := -2147483648
|
||||
INT64_MIN := -9223372036854775808
|
||||
|
||||
INT8_MAX := 127
|
||||
INT16_MAX := 32767
|
||||
INT32_MAX := 2147483647
|
||||
INT64_MAX := 9223372036854775807
|
||||
|
||||
UINT8_MAX := 255
|
||||
UINT16_MAX := 65535
|
||||
UINT32_MAX := 4294967295
|
||||
UINT64_MAX := 18446744073709551615
|
||||
@@ -5,8 +5,6 @@
|
||||
# Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source "Kconfig.constants"
|
||||
|
||||
osource "${APPLICATION_SOURCE_DIR}/VERSION"
|
||||
|
||||
# Include Kconfig.defconfig files first so that they can override defaults and
|
||||
@@ -822,23 +820,6 @@ config BUILD_OUTPUT_ADJUST_LMA
|
||||
default "$(dt_chosen_reg_addr_hex,$(DT_CHOSEN_IMAGE_M4))-\
|
||||
$(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH))"
|
||||
|
||||
config BUILD_OUTPUT_ADJUST_LMA_SECTIONS
|
||||
def_string "*"
|
||||
depends on BUILD_OUTPUT_ADJUST_LMA!=""
|
||||
help
|
||||
This determines the output sections to which the above LMA adjustment
|
||||
will be applied.
|
||||
The value can be the name of a section in the final ELF, like "text".
|
||||
It can also be a pattern with wildcards, such as "*bss", which could
|
||||
match more than one section name. Multiple such patterns can be given
|
||||
as a ";"-separated list. It's possible to supply a 'negative' pattern
|
||||
starting with "!", to exclude sections matched by a preceding pattern.
|
||||
|
||||
By default, all sections will have their LMA adjusted. The following
|
||||
example excludes one section produced by the code relocation feature:
|
||||
config BUILD_OUTPUT_ADJUST_LMA_SECTIONS
|
||||
default "*;!.extflash_text_reloc"
|
||||
|
||||
config BUILD_OUTPUT_INFO_HEADER
|
||||
bool "Create a image information header"
|
||||
help
|
||||
@@ -949,8 +930,6 @@ config DEPRECATED
|
||||
help
|
||||
Symbol that must be selected by a feature or module if it is
|
||||
considered to be deprecated.
|
||||
When adding this to an option, remember to follow the instructions in
|
||||
https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated
|
||||
|
||||
config WARN_DEPRECATED
|
||||
bool
|
||||
|
||||
461
MAINTAINERS.yml
461
MAINTAINERS.yml
File diff suppressed because it is too large
Load Diff
15
README.rst
15
README.rst
@@ -10,15 +10,12 @@
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a href="https://bestpractices.coreinfrastructure.org/projects/74">
|
||||
<img src="https://bestpractices.coreinfrastructure.org/projects/74/badge">
|
||||
</a>
|
||||
<a href="https://scorecard.dev/viewer/?uri=github.com/zephyrproject-rtos/zephyr">
|
||||
<img src="https://api.securityscorecards.dev/projects/github.com/zephyrproject-rtos/zephyr/badge">
|
||||
</a>
|
||||
<a href="https://github.com/zephyrproject-rtos/zephyr/actions/workflows/twister.yaml?query=branch%3Amain">
|
||||
<img src="https://github.com/zephyrproject-rtos/zephyr/actions/workflows/twister.yaml/badge.svg?event=push">
|
||||
</a>
|
||||
<a href="https://bestpractices.coreinfrastructure.org/projects/74"><img
|
||||
src="https://bestpractices.coreinfrastructure.org/projects/74/badge"></a>
|
||||
<a
|
||||
href="https://github.com/zephyrproject-rtos/zephyr/actions/workflows/twister.yaml?query=branch%3Amain">
|
||||
<img
|
||||
src="https://github.com/zephyrproject-rtos/zephyr/actions/workflows/twister.yaml/badge.svg?event=push"></a>
|
||||
|
||||
|
||||
The Zephyr Project is a scalable real-time operating system (RTOS) supporting
|
||||
|
||||
4
VERSION
4
VERSION
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 3
|
||||
VERSION_MINOR = 7
|
||||
PATCHLEVEL = 99
|
||||
PATCHLEVEL = 0
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = rc1
|
||||
|
||||
29
arch/Kconfig
29
arch/Kconfig
@@ -32,7 +32,6 @@ config ARM
|
||||
bool
|
||||
select ARCH_IS_SET
|
||||
select ARCH_SUPPORTS_COREDUMP if CPU_CORTEX_M
|
||||
select ARCH_SUPPORTS_COREDUMP_THREADS if CPU_CORTEX_M
|
||||
# FIXME: current state of the code for all ARM requires this, but
|
||||
# is really only necessary for Cortex-M with ARM MPU!
|
||||
select GEN_PRIV_STACKS
|
||||
@@ -655,9 +654,6 @@ config ARCH_HAS_NESTED_EXCEPTION_DETECTION
|
||||
config ARCH_SUPPORTS_COREDUMP
|
||||
bool
|
||||
|
||||
config ARCH_SUPPORTS_COREDUMP_THREADS
|
||||
bool
|
||||
|
||||
config ARCH_SUPPORTS_ARCH_HW_INIT
|
||||
bool
|
||||
|
||||
@@ -1078,28 +1074,9 @@ config TOOLCHAIN_HAS_BUILTIN_FFS
|
||||
help
|
||||
Hidden option to signal that toolchain has __builtin_ffs*().
|
||||
|
||||
config ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
bool
|
||||
config ARCH_CPU_IDLE_CUSTOM
|
||||
bool "Custom arch_cpu_idle implementation"
|
||||
default n
|
||||
help
|
||||
This options allows applications to override the default arch idle implementation with
|
||||
a custom one.
|
||||
|
||||
config ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
bool
|
||||
help
|
||||
This options allows applications to override the default arch idle implementation with
|
||||
a custom one.
|
||||
|
||||
config ARCH_HAS_CUSTOM_SWAP_TO_MAIN
|
||||
bool
|
||||
help
|
||||
It's possible that an architecture port cannot use _Swap() to swap to
|
||||
the _main() thread, but instead must do something custom. It must
|
||||
enable this option in that case.
|
||||
|
||||
config ARCH_HAS_CUSTOM_BUSY_WAIT
|
||||
bool
|
||||
help
|
||||
It's possible that an architecture port cannot or does not want to use
|
||||
the provided k_busy_wait(), but instead must do something custom. It must
|
||||
enable this option in that case.
|
||||
|
||||
@@ -26,7 +26,6 @@ SECTION_VAR(BSS, z_arc_cpu_sleep_mode)
|
||||
.align 4
|
||||
.word 0
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
/*
|
||||
* @brief Put the CPU in low-power mode
|
||||
*
|
||||
@@ -49,9 +48,7 @@ SECTION_FUNC(TEXT, arch_cpu_idle)
|
||||
sleep r1
|
||||
j_s [blink]
|
||||
nop
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
/*
|
||||
* @brief Put the CPU in low-power mode, entered with IRQs locked
|
||||
*
|
||||
@@ -59,7 +56,6 @@ SECTION_FUNC(TEXT, arch_cpu_idle)
|
||||
*
|
||||
* void arch_cpu_atomic_idle(unsigned int key)
|
||||
*/
|
||||
|
||||
SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
|
||||
|
||||
#ifdef CONFIG_TRACING
|
||||
@@ -74,4 +70,3 @@ SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
|
||||
sleep r1
|
||||
j_s.d [blink]
|
||||
seti r0
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if(CONFIG_BIG_ENDIAN)
|
||||
set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-bigarm)
|
||||
else()
|
||||
set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-littlearm)
|
||||
endif()
|
||||
set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-littlearm)
|
||||
|
||||
add_subdirectory(core)
|
||||
|
||||
@@ -26,6 +26,5 @@ extern void __start(void);
|
||||
#define BOOT_PARAM_UDF_SP_OFFSET 16
|
||||
#define BOOT_PARAM_SVC_SP_OFFSET 20
|
||||
#define BOOT_PARAM_SYS_SP_OFFSET 24
|
||||
#define BOOT_PARAM_VOTING_OFFSET 28
|
||||
|
||||
#endif /* _BOOT_H_ */
|
||||
|
||||
@@ -49,7 +49,6 @@ _skip_\@:
|
||||
#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */
|
||||
.endm
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
SECTION_FUNC(TEXT, arch_cpu_idle)
|
||||
#ifdef CONFIG_TRACING
|
||||
push {r0, lr}
|
||||
@@ -69,9 +68,6 @@ SECTION_FUNC(TEXT, arch_cpu_idle)
|
||||
|
||||
bx lr
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
|
||||
#ifdef CONFIG_TRACING
|
||||
push {r0, lr}
|
||||
@@ -97,4 +93,3 @@ SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
|
||||
_irq_disabled:
|
||||
|
||||
bx lr
|
||||
#endif
|
||||
|
||||
@@ -339,15 +339,6 @@ z_arm_cortex_ar_irq_done:
|
||||
str r0, [r2, #___cpu_t_nested_OFFSET]
|
||||
/* Do not context switch if exiting a nested interrupt */
|
||||
cmp r0, #0
|
||||
/* Note that this function is only called from `z_arm_svc`,
|
||||
* while handling irq_offload, with below modes set:
|
||||
* ```
|
||||
* if (cpu interrupts are nested)
|
||||
* mode=MODE_SYS
|
||||
* else
|
||||
* mode=MODE_IRQ
|
||||
* ```
|
||||
*/
|
||||
bhi __EXIT_INT
|
||||
|
||||
/* retrieve pointer to the current thread */
|
||||
|
||||
@@ -18,27 +18,6 @@
|
||||
ubfx \rreg0, \rreg0, #0, #24
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Get CPU logic id by looking up cpu_node_list
|
||||
* returns
|
||||
* reg0: MPID
|
||||
* reg1: logic id (0 ~ CONFIG_MP_MAX_NUM_CPUS - 1)
|
||||
* clobbers: reg0, reg1, reg2, reg3
|
||||
*/
|
||||
.macro get_cpu_logic_id reg0, reg1, reg2, reg3
|
||||
get_cpu_id \reg0
|
||||
ldr \reg3, =cpu_node_list
|
||||
mov \reg1, #0
|
||||
1: ldr \reg2, [\reg3, \reg1, lsl #2]
|
||||
cmp \reg2, \reg0
|
||||
beq 2f
|
||||
add \reg1, \reg1, #1
|
||||
cmp \reg1, #CONFIG_MP_MAX_NUM_CPUS
|
||||
bne 1b
|
||||
b .
|
||||
2:
|
||||
.endm
|
||||
|
||||
.macro get_cpu rreg0
|
||||
/*
|
||||
* Get CPU pointer.
|
||||
@@ -54,7 +33,8 @@
|
||||
*/
|
||||
srsdb sp!, #MODE_SYS
|
||||
cps #MODE_SYS
|
||||
push {r0-r3, r12, lr}
|
||||
stmdb sp, {r0-r3, r12, lr}^
|
||||
sub sp, #24
|
||||
|
||||
/* TODO: EXTRA_EXCEPTION_INFO */
|
||||
mov r0, sp
|
||||
|
||||
@@ -200,62 +200,23 @@ EL1_Reset_Handler:
|
||||
#endif /* CONFIG_DCLS */
|
||||
|
||||
ldr r0, =arm_cpu_boot_params
|
||||
|
||||
#if CONFIG_MP_MAX_NUM_CPUS > 1
|
||||
/*
|
||||
* This code uses voting locks, like arch/arm64/core/reset.S, to determine primary CPU.
|
||||
*/
|
||||
get_cpu_id r1
|
||||
|
||||
/*
|
||||
* Get the "logic" id defined by cpu_node_list statically for voting lock self-identify.
|
||||
* It is worth noting that this is NOT the final logic id (arch_curr_cpu()->id)
|
||||
*/
|
||||
get_cpu_logic_id r1, r2, r3, r4 // r1: MPID, r2: logic id
|
||||
|
||||
add r4, r0, #BOOT_PARAM_VOTING_OFFSET
|
||||
|
||||
/* signal our desire to vote */
|
||||
mov r5, #1
|
||||
strb r5, [r4, r2]
|
||||
ldr r3, [r0, #BOOT_PARAM_MPID_OFFSET]
|
||||
cmn r3, #1
|
||||
beq 1f
|
||||
|
||||
/* some core already won, release */
|
||||
mov r7, #0
|
||||
strb r7, [r4, r2]
|
||||
b _secondary_core
|
||||
|
||||
/* suggest current core then release */
|
||||
1: str r1, [r0, #BOOT_PARAM_MPID_OFFSET]
|
||||
strb r7, [r4, r2]
|
||||
dmb
|
||||
|
||||
/* then wait until every core else is done voting */
|
||||
mov r5, #0
|
||||
2: ldrb r3, [r4, r5]
|
||||
tst r3, #255
|
||||
/* wait */
|
||||
bne 2b
|
||||
add r5, r5, #1
|
||||
cmp r5, #CONFIG_MP_MAX_NUM_CPUS
|
||||
bne 2b
|
||||
|
||||
/* check if current core won */
|
||||
dmb
|
||||
ldr r3, [r0, #BOOT_PARAM_MPID_OFFSET]
|
||||
cmp r3, r1
|
||||
ldrex r2, [r0, #BOOT_PARAM_MPID_OFFSET]
|
||||
cmp r2, #-1
|
||||
bne 1f
|
||||
strex r3, r1, [r0, #BOOT_PARAM_MPID_OFFSET]
|
||||
cmp r3, #0
|
||||
beq _primary_core
|
||||
/* fallthrough secondary */
|
||||
|
||||
/* loop until our turn comes */
|
||||
_secondary_core:
|
||||
dmb
|
||||
1:
|
||||
dmb ld
|
||||
ldr r2, [r0, #BOOT_PARAM_MPID_OFFSET]
|
||||
cmp r1, r2
|
||||
bne _secondary_core
|
||||
bne 1b
|
||||
|
||||
/* we can now load our stack pointer values and move on */
|
||||
/* we can now move on */
|
||||
ldr r4, =arch_secondary_cpu_init
|
||||
ldr r5, [r0, #BOOT_PARAM_FIQ_SP_OFFSET]
|
||||
ldr r6, [r0, #BOOT_PARAM_IRQ_SP_OFFSET]
|
||||
|
||||
@@ -51,7 +51,6 @@ struct boot_params {
|
||||
char *udf_sp;
|
||||
char *svc_sp;
|
||||
char *sys_sp;
|
||||
uint8_t voting[CONFIG_MP_MAX_NUM_CPUS];
|
||||
arch_cpustart_t fn;
|
||||
void *arg;
|
||||
int cpu_num;
|
||||
@@ -65,7 +64,6 @@ BUILD_ASSERT(offsetof(struct boot_params, abt_sp) == BOOT_PARAM_ABT_SP_OFFSET);
|
||||
BUILD_ASSERT(offsetof(struct boot_params, udf_sp) == BOOT_PARAM_UDF_SP_OFFSET);
|
||||
BUILD_ASSERT(offsetof(struct boot_params, svc_sp) == BOOT_PARAM_SVC_SP_OFFSET);
|
||||
BUILD_ASSERT(offsetof(struct boot_params, sys_sp) == BOOT_PARAM_SYS_SP_OFFSET);
|
||||
BUILD_ASSERT(offsetof(struct boot_params, voting) == BOOT_PARAM_VOTING_OFFSET);
|
||||
|
||||
volatile struct boot_params arm_cpu_boot_params = {
|
||||
.mpid = -1,
|
||||
@@ -77,7 +75,7 @@ volatile struct boot_params arm_cpu_boot_params = {
|
||||
.sys_sp = (char *)(z_arm_sys_stack + CONFIG_ARMV7_SYS_STACK_SIZE),
|
||||
};
|
||||
|
||||
const uint32_t cpu_node_list[] = {
|
||||
static const uint32_t cpu_node_list[] = {
|
||||
DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_REG_ADDR, (,))};
|
||||
|
||||
/* cpu_map saves the maping of core id and mpid */
|
||||
|
||||
@@ -95,10 +95,6 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
|
||||
iframe->a4 = (uint32_t)p3;
|
||||
|
||||
iframe->xpsr = A_BIT | MODE_SYS;
|
||||
#if defined(CONFIG_BIG_ENDIAN)
|
||||
iframe->xpsr |= E_BIT;
|
||||
#endif /* CONFIG_BIG_ENDIAN */
|
||||
|
||||
#if defined(CONFIG_COMPILER_ISA_THUMB2)
|
||||
iframe->xpsr |= T_BIT;
|
||||
#endif /* CONFIG_COMPILER_ISA_THUMB2 */
|
||||
|
||||
@@ -41,11 +41,6 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table)
|
||||
GTEXT(z_arm_cortex_ar_exit_exc)
|
||||
SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_cortex_ar_exit_exc)
|
||||
|
||||
/* Note:
|
||||
* This function is expected to be *always* called with
|
||||
* processor mode set to MODE_SYS.
|
||||
*/
|
||||
|
||||
/* decrement exception depth */
|
||||
get_cpu r2
|
||||
ldrb r1, [r2, #_cpu_offset_to_exc_depth]
|
||||
@@ -56,6 +51,7 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_cortex_ar_exit_exc)
|
||||
* Restore r0-r3, r12, lr, lr_und and spsr_und from the exception stack
|
||||
* and return to the current thread.
|
||||
*/
|
||||
pop {r0-r3, r12, lr}
|
||||
ldmia sp, {r0-r3, r12, lr}^
|
||||
add sp, #24
|
||||
rfeia sp!
|
||||
#endif
|
||||
|
||||
@@ -330,7 +330,7 @@ config ZERO_LATENCY_IRQS
|
||||
config ZERO_LATENCY_LEVELS
|
||||
int "Number of interrupt priority levels reserved for zero latency"
|
||||
depends on ZERO_LATENCY_IRQS
|
||||
range 1 $(UINT8_MAX)
|
||||
range 1 255
|
||||
help
|
||||
The amount of interrupt priority levels reserved for zero latency
|
||||
interrupts. Increase this value to reserve more than one priority
|
||||
|
||||
@@ -53,7 +53,6 @@ void z_arm_cpu_idle_init(void)
|
||||
} while (false)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
#if defined(CONFIG_TRACING)
|
||||
@@ -97,9 +96,7 @@ void arch_cpu_idle(void)
|
||||
__enable_irq();
|
||||
__ISB();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
void arch_cpu_atomic_idle(unsigned int key)
|
||||
{
|
||||
#if defined(CONFIG_TRACING)
|
||||
@@ -138,4 +135,3 @@ void arch_cpu_atomic_idle(unsigned int key)
|
||||
__enable_irq();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1192,7 +1192,5 @@ void z_arm_fault_init(void)
|
||||
#endif /* CONFIG_BUILTIN_STACK_GUARD */
|
||||
#ifdef CONFIG_TRAP_UNALIGNED_ACCESS
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#else
|
||||
SCB->CCR &= ~SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif /* CONFIG_TRAP_UNALIGNED_ACCESS */
|
||||
}
|
||||
|
||||
@@ -588,7 +588,7 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr,
|
||||
"bx r4\n" /* We don’t intend to return, so there is no need to link. */
|
||||
: "+r" (_main)
|
||||
: "r" (stack_ptr)
|
||||
: "r0", "r1", "r2", "r3", "r4", "ip", "lr");
|
||||
: "r0", "r1", "r2", "r3", "r4");
|
||||
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
@@ -659,7 +659,7 @@ FUNC_NORETURN void z_arm_switch_to_main_no_multithreading(
|
||||
#ifdef CONFIG_BUILTIN_STACK_GUARD
|
||||
, [_psplim]"r" (psplim)
|
||||
#endif
|
||||
: "r0", "r1", "r2", "ip", "lr"
|
||||
: "r0", "r1", "r2", "r3"
|
||||
);
|
||||
|
||||
CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <zephyr/arch/cpu.h>
|
||||
|
||||
_ASM_FILE_PROLOGUE
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
|
||||
GTEXT(arch_cpu_idle)
|
||||
SECTION_FUNC(TEXT, arch_cpu_idle)
|
||||
#ifdef CONFIG_TRACING
|
||||
@@ -25,9 +25,7 @@ SECTION_FUNC(TEXT, arch_cpu_idle)
|
||||
wfi
|
||||
msr daifclr, #(DAIFCLR_IRQ_BIT)
|
||||
ret
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
GTEXT(arch_cpu_atomic_idle)
|
||||
SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
|
||||
#ifdef CONFIG_TRACING
|
||||
@@ -43,5 +41,3 @@ SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
|
||||
msr daifclr, #(DAIFCLR_IRQ_BIT)
|
||||
_irq_disabled:
|
||||
ret
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,11 +17,6 @@ if(CONFIG_GEN_ISR_TABLES)
|
||||
)
|
||||
endif()
|
||||
|
||||
zephyr_library_sources_ifdef(
|
||||
CONFIG_ISR_TABLE_SHELL
|
||||
isr_tables_shell.c
|
||||
)
|
||||
|
||||
zephyr_library_sources_ifdef(
|
||||
CONFIG_MULTI_LEVEL_INTERRUPTS
|
||||
multilevel_irq.c
|
||||
|
||||
@@ -30,10 +30,3 @@ config LEGACY_MULTI_LEVEL_TABLE_GENERATION
|
||||
help
|
||||
A make-shift Kconfig to continue generating the multi-level interrupt LUT
|
||||
with the legacy way using DT macros.
|
||||
|
||||
config ISR_TABLE_SHELL
|
||||
bool "Shell command to dump the ISR tables"
|
||||
depends on GEN_SW_ISR_TABLE
|
||||
depends on SHELL
|
||||
help
|
||||
This option enables a shell command to dump the ISR tables.
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
struct int_list_header {
|
||||
uint32_t table_size;
|
||||
uint32_t offset;
|
||||
#if defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION)
|
||||
#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION)
|
||||
uint32_t swi_table_entry_size;
|
||||
uint32_t shared_isr_table_entry_size;
|
||||
uint32_t shared_isr_client_num_offset;
|
||||
#endif /* defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */
|
||||
#endif /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */
|
||||
};
|
||||
|
||||
/* These values are not included in the resulting binary, but instead form the
|
||||
@@ -29,13 +29,13 @@ struct int_list_header {
|
||||
Z_GENERIC_SECTION(.irq_info) __used struct int_list_header _iheader = {
|
||||
.table_size = IRQ_TABLE_SIZE,
|
||||
.offset = CONFIG_GEN_IRQ_START_VECTOR,
|
||||
#if defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION)
|
||||
#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION)
|
||||
.swi_table_entry_size = sizeof(struct _isr_table_entry),
|
||||
#if defined(CONFIG_SHARED_INTERRUPTS)
|
||||
#if IS_ENABLED(CONFIG_SHARED_INTERRUPTS)
|
||||
.shared_isr_table_entry_size = sizeof(struct z_shared_isr_table_entry),
|
||||
.shared_isr_client_num_offset = offsetof(struct z_shared_isr_table_entry, client_num),
|
||||
#endif /* defined(CONFIG_SHARED_INTERRUPTS) */
|
||||
#endif /* defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */
|
||||
#endif /* IS_ENABLED(CONFIG_SHARED_INTERRUPTS) */
|
||||
#endif /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */
|
||||
};
|
||||
|
||||
/* These are placeholder tables. They will be replaced by the real tables
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Meta Platforms.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/debug/symtab.h>
|
||||
#include <zephyr/shell/shell.h>
|
||||
#include <zephyr/sw_isr_table.h>
|
||||
|
||||
static void dump_isr_table_entry(const struct shell *sh, int idx, struct _isr_table_entry *entry)
|
||||
{
|
||||
|
||||
if ((entry->isr == z_irq_spurious) || (entry->isr == NULL)) {
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_SYMTAB
|
||||
const char *name = symtab_find_symbol_name((uintptr_t)entry->isr, NULL);
|
||||
|
||||
shell_print(sh, "%4d: %s(%p)", idx, name, entry->arg);
|
||||
#else
|
||||
shell_print(sh, "%4d: %p(%p)", idx, entry->isr, entry->arg);
|
||||
#endif /* CONFIG_SYMTAB */
|
||||
}
|
||||
|
||||
static int cmd_sw_isr_table(const struct shell *sh, size_t argc, char **argv)
|
||||
{
|
||||
shell_print(sh, "_sw_isr_table[%d]\n", IRQ_TABLE_SIZE);
|
||||
|
||||
for (int idx = 0; idx < IRQ_TABLE_SIZE; idx++) {
|
||||
dump_isr_table_entry(sh, idx, &_sw_isr_table[idx]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SHARED_INTERRUPTS
|
||||
static int cmd_shared_sw_isr_table(const struct shell *sh, size_t argc, char **argv)
|
||||
{
|
||||
shell_print(sh, "z_shared_sw_isr_table[%d][%d]\n", IRQ_TABLE_SIZE,
|
||||
CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS);
|
||||
|
||||
for (int idx = 0; idx < IRQ_TABLE_SIZE; idx++) {
|
||||
for (int c = 0; c < z_shared_sw_isr_table[idx].client_num; c++) {
|
||||
dump_isr_table_entry(sh, idx, &z_shared_sw_isr_table[idx].clients[c]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SHARED_INTERRUPTS */
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(isr_table_cmds,
|
||||
SHELL_CMD_ARG(sw_isr_table, NULL,
|
||||
"Dump _sw_isr_table.\n"
|
||||
"Usage: isr_table sw_isr_table",
|
||||
cmd_sw_isr_table, 1, 0),
|
||||
#ifdef CONFIG_SHARED_INTERRUPTS
|
||||
SHELL_CMD_ARG(shared_sw_isr_table, NULL,
|
||||
"Dump z_shared_sw_isr_table.\n"
|
||||
"Usage: isr_table shared_sw_isr_table",
|
||||
cmd_shared_sw_isr_table, 1, 0),
|
||||
#endif /* CONFIG_SHARED_INTERRUPTS */
|
||||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
SHELL_CMD_ARG_REGISTER(isr_table, &isr_table_cmds, "ISR tables shell command",
|
||||
NULL, 0, 0);
|
||||
@@ -19,16 +19,12 @@ static ALWAYS_INLINE void mips_idle(unsigned int key)
|
||||
__asm__ volatile("wait");
|
||||
}
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
mips_idle(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
void arch_cpu_atomic_idle(unsigned int key)
|
||||
{
|
||||
mips_idle(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/kernel_structs.h>
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
/* Do nothing but unconditionally unlock interrupts and return to the
|
||||
@@ -15,9 +14,7 @@ void arch_cpu_idle(void)
|
||||
*/
|
||||
irq_unlock(NIOS2_STATUS_PIE_MSK);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
void arch_cpu_atomic_idle(unsigned int key)
|
||||
{
|
||||
/* Do nothing but restore IRQ state. This CPU does not have any
|
||||
@@ -25,4 +22,3 @@ void arch_cpu_atomic_idle(unsigned int key)
|
||||
*/
|
||||
irq_unlock(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,12 +21,10 @@ endif()
|
||||
if(CONFIG_NATIVE_APPLICATION)
|
||||
zephyr_include_directories(
|
||||
nsi_compat/
|
||||
${ZEPHYR_BASE}/scripts/native_simulator/common/src/include/
|
||||
)
|
||||
zephyr_library_sources(
|
||||
posix_core_nsi.c
|
||||
posix_core.c
|
||||
nsi_compat/nsi_compat.c
|
||||
${ZEPHYR_BASE}/scripts/native_simulator/common/src/nct.c
|
||||
${ZEPHYR_BASE}/scripts/native_simulator/common/src/nce.c
|
||||
${ZEPHYR_BASE}/scripts/native_simulator/common/src/nsi_host_trampolines.c
|
||||
)
|
||||
|
||||
26
arch/posix/core/nsi_compat/nce_if.h
Normal file
26
arch/posix/core/nsi_compat/nce_if.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef NSI_COMMON_SRC_INCL_NCE_IF_H
|
||||
#define NSI_COMMON_SRC_INCL_NCE_IF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Native simulator CPU start/stop emulation module interface */
|
||||
|
||||
void *nce_init(void);
|
||||
void nce_terminate(void *this);
|
||||
void nce_boot_cpu(void *this, void (*start_routine)(void));
|
||||
void nce_halt_cpu(void *this);
|
||||
void nce_wake_cpu(void *this);
|
||||
int nce_is_cpu_running(void *this);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NSI_COMMON_SRC_INCL_NCE_IF_H */
|
||||
19
arch/posix/core/nsi_compat/nsi_host_trampolines.h
Normal file
19
arch/posix/core/nsi_compat/nsi_host_trampolines.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Note: This is a provisional header which exists to allow
|
||||
* old POSIX arch based boards (i.e. native_posix) to provide access
|
||||
* to the host C library as if the native simulator trampolines
|
||||
* existed.
|
||||
*
|
||||
* Boards based on the native simulator do NOT use this file
|
||||
*/
|
||||
|
||||
#ifndef ARCH_POSIX_CORE_NSI_COMPAT_NSI_HOST_TRAMPOLINES_H
|
||||
#define ARCH_POSIX_CORE_NSI_COMPAT_NSI_HOST_TRAMPOLINES_H
|
||||
|
||||
#include "../scripts/native_simulator/common/src/include/nsi_host_trampolines.h"
|
||||
|
||||
#endif /* ARCH_POSIX_CORE_NSI_COMPAT_NSI_HOST_TRAMPOLINES_H */
|
||||
15
arch/posix/core/nsi_compat/nsi_safe_call.h
Normal file
15
arch/posix/core/nsi_compat/nsi_safe_call.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ARCH_POSIX_CORE_NSI_SAFE_CALLL_H
|
||||
#define ARCH_POSIX_CORE_NSI_SAFE_CALLL_H
|
||||
|
||||
#include "nsi_tracing.h"
|
||||
#include "posix_arch_internal.h"
|
||||
|
||||
#define NSI_SAFE_CALL PC_SAFE_CALL
|
||||
|
||||
#endif /* ARCH_POSIX_CORE_NSI_SAFE_CALLL_H */
|
||||
22
arch/posix/core/nsi_compat/nsi_tracing.h
Normal file
22
arch/posix/core/nsi_compat/nsi_tracing.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ARCH_POSIX_CORE_NSI_TRACING_H
|
||||
#define ARCH_POSIX_CORE_NSI_TRACING_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void nsi_print_error_and_exit(const char *format, ...);
|
||||
void nsi_print_warning(const char *format, ...);
|
||||
void nsi_print_trace(const char *format, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ARCH_POSIX_CORE_NSI_TRACING_H */
|
||||
539
arch/posix/core/posix_core.c
Normal file
539
arch/posix/core/posix_core.c
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Oticon A/S
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Here is where things actually happen for the POSIX arch
|
||||
*
|
||||
* We isolate all functions here, to ensure they can be compiled as
|
||||
* independently as possible to the remainder of Zephyr to avoid name clashes
|
||||
* as Zephyr does provide functions with the same names as the POSIX threads
|
||||
* functions
|
||||
*/
|
||||
/**
|
||||
* Principle of operation:
|
||||
*
|
||||
* The Zephyr OS and its app run as a set of native pthreads.
|
||||
* The Zephyr OS only sees one of this thread executing at a time.
|
||||
* Which is running is controlled using {cond|mtx}_threads and
|
||||
* currently_allowed_thread.
|
||||
*
|
||||
* The main part of the execution of each thread will occur in a fully
|
||||
* synchronous and deterministic manner, and only when commanded by the Zephyr
|
||||
* kernel.
|
||||
* But the creation of a thread will spawn a new pthread whose start
|
||||
* is asynchronous to the rest, until synchronized in posix_wait_until_allowed()
|
||||
* below.
|
||||
* Similarly aborting and canceling threads execute a tail in a quite
|
||||
* asynchronous manner.
|
||||
*
|
||||
* This implementation is meant to be portable in between POSIX systems.
|
||||
* A table (threads_table) is used to abstract the native pthreads.
|
||||
* And index in this table is used to identify threads in the IF to the kernel.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "posix_core.h"
|
||||
#include "posix_arch_internal.h"
|
||||
|
||||
#define PREFIX "POSIX arch core: "
|
||||
#define ERPREFIX PREFIX"error on "
|
||||
#define NO_MEM_ERR PREFIX"Can't allocate memory\n"
|
||||
|
||||
#define PC_ENABLE_CANCEL 0 /* See Note.c1 */
|
||||
#define PC_ALLOC_CHUNK_SIZE 64
|
||||
#define PC_REUSE_ABORTED_ENTRIES 0
|
||||
/* tests/kernel/threads/scheduling/schedule_api fails when setting
|
||||
* PC_REUSE_ABORTED_ENTRIES => don't set it by now
|
||||
*/
|
||||
|
||||
static int threads_table_size;
|
||||
struct threads_table_el {
|
||||
enum {NOTUSED = 0, USED, ABORTING, ABORTED, FAILED} state;
|
||||
bool running; /* Is this the currently running thread */
|
||||
pthread_t thread; /* Actual pthread_t as returned by native kernel */
|
||||
int thead_cnt; /* For debugging: Unique, consecutive, thread number */
|
||||
/* Pointer to the status kept in the Zephyr thread stack */
|
||||
posix_thread_status_t *t_status;
|
||||
};
|
||||
|
||||
static struct threads_table_el *threads_table;
|
||||
|
||||
static int thread_create_count; /* For debugging. Thread creation counter */
|
||||
|
||||
/*
|
||||
* Conditional variable to block/awake all threads during swaps()
|
||||
* (we only need 1 mutex and 1 cond variable for all threads)
|
||||
*/
|
||||
static pthread_cond_t cond_threads = PTHREAD_COND_INITIALIZER;
|
||||
/* Mutex for the conditional variable posix_core_cond_threads */
|
||||
static pthread_mutex_t mtx_threads = PTHREAD_MUTEX_INITIALIZER;
|
||||
/* Token which tells which process is allowed to run now */
|
||||
static int currently_allowed_thread;
|
||||
|
||||
static bool terminate; /* Are we terminating the program == cleaning up */
|
||||
|
||||
static void posix_wait_until_allowed(int this_th_nbr);
|
||||
static void *posix_thread_starter(void *arg);
|
||||
static void posix_preexit_cleanup(void);
|
||||
extern void posix_arch_thread_entry(void *pa_thread_status);
|
||||
|
||||
/**
|
||||
* Helper function, run by a thread is being aborted
|
||||
*/
|
||||
static void abort_tail(int this_th_nbr)
|
||||
{
|
||||
PC_DEBUG("Thread [%i] %i: %s: Aborting (exiting) (rel mut)\n",
|
||||
threads_table[this_th_nbr].thead_cnt,
|
||||
this_th_nbr,
|
||||
__func__);
|
||||
|
||||
threads_table[this_th_nbr].running = false;
|
||||
threads_table[this_th_nbr].state = ABORTED;
|
||||
posix_preexit_cleanup();
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to block this thread until it is allowed again
|
||||
* (somebody calls posix_let_run() with this thread number
|
||||
*
|
||||
* Note that we go out of this function (the while loop below)
|
||||
* with the mutex locked by this particular thread.
|
||||
* In normal circumstances, the mutex is only unlocked internally in
|
||||
* pthread_cond_wait() while waiting for cond_threads to be signaled
|
||||
*/
|
||||
static void posix_wait_until_allowed(int this_th_nbr)
|
||||
{
|
||||
threads_table[this_th_nbr].running = false;
|
||||
|
||||
PC_DEBUG("Thread [%i] %i: %s: Waiting to be allowed to run (rel mut)\n",
|
||||
threads_table[this_th_nbr].thead_cnt,
|
||||
this_th_nbr,
|
||||
__func__);
|
||||
|
||||
while (this_th_nbr != currently_allowed_thread) {
|
||||
pthread_cond_wait(&cond_threads, &mtx_threads);
|
||||
|
||||
if (threads_table &&
|
||||
(threads_table[this_th_nbr].state == ABORTING)) {
|
||||
abort_tail(this_th_nbr);
|
||||
}
|
||||
}
|
||||
|
||||
threads_table[this_th_nbr].running = true;
|
||||
|
||||
PC_DEBUG("Thread [%i] %i: %s(): I'm allowed to run! (hav mut)\n",
|
||||
threads_table[this_th_nbr].thead_cnt,
|
||||
this_th_nbr,
|
||||
__func__);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to let the thread <next_allowed_th> run
|
||||
* Note: posix_let_run() can only be called with the mutex locked
|
||||
*/
|
||||
static void posix_let_run(int next_allowed_th)
|
||||
{
|
||||
PC_DEBUG("%s: We let thread [%i] %i run\n",
|
||||
__func__,
|
||||
threads_table[next_allowed_th].thead_cnt,
|
||||
next_allowed_th);
|
||||
|
||||
|
||||
currently_allowed_thread = next_allowed_th;
|
||||
|
||||
/*
|
||||
* We let all threads know one is able to run now (it may even be us
|
||||
* again if fancied)
|
||||
* Note that as we hold the mutex, they are going to be blocked until
|
||||
* we reach our own posix_wait_until_allowed() while loop
|
||||
*/
|
||||
PC_SAFE_CALL(pthread_cond_broadcast(&cond_threads));
|
||||
}
|
||||
|
||||
|
||||
static void posix_preexit_cleanup(void)
|
||||
{
|
||||
/*
|
||||
* Release the mutex so the next allowed thread can run
|
||||
*/
|
||||
PC_SAFE_CALL(pthread_mutex_unlock(&mtx_threads));
|
||||
|
||||
/* We detach ourselves so nobody needs to join to us */
|
||||
pthread_detach(pthread_self());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Let the ready thread run and block this thread until it is allowed again
|
||||
*
|
||||
* called from arch_swap() which does the picking from the kernel structures
|
||||
*/
|
||||
void posix_swap(int next_allowed_thread_nbr, int this_th_nbr)
|
||||
{
|
||||
posix_let_run(next_allowed_thread_nbr);
|
||||
|
||||
if (threads_table[this_th_nbr].state == ABORTING) {
|
||||
PC_DEBUG("Thread [%i] %i: %s: Aborting curr.\n",
|
||||
threads_table[this_th_nbr].thead_cnt,
|
||||
this_th_nbr,
|
||||
__func__);
|
||||
abort_tail(this_th_nbr);
|
||||
} else {
|
||||
posix_wait_until_allowed(this_th_nbr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the ready thread (main) run, and exit this thread (init)
|
||||
*
|
||||
* Called from arch_switch_to_main_thread() which does the picking from the
|
||||
* kernel structures
|
||||
*
|
||||
* Note that we could have just done a swap(), but that would have left the
|
||||
* init thread lingering. Instead here we exit the init thread after enabling
|
||||
* the new one
|
||||
*/
|
||||
void posix_main_thread_start(int next_allowed_thread_nbr)
|
||||
{
|
||||
posix_let_run(next_allowed_thread_nbr);
|
||||
PC_DEBUG("%s: Init thread dying now (rel mut)\n",
|
||||
__func__);
|
||||
posix_preexit_cleanup();
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler called when any thread is cancelled or exits
|
||||
*/
|
||||
static void posix_cleanup_handler(void *arg)
|
||||
{
|
||||
/*
|
||||
* If we are not terminating, this is just an aborted thread,
|
||||
* and the mutex was already released
|
||||
* Otherwise, release the mutex so other threads which may be
|
||||
* caught waiting for it could terminate
|
||||
*/
|
||||
|
||||
if (!terminate) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if POSIX_ARCH_DEBUG_PRINTS
|
||||
posix_thread_status_t *ptr = (posix_thread_status_t *) arg;
|
||||
|
||||
PC_DEBUG("Thread %i: %s: Canceling (rel mut)\n",
|
||||
ptr->thread_idx,
|
||||
__func__);
|
||||
#endif
|
||||
|
||||
|
||||
PC_SAFE_CALL(pthread_mutex_unlock(&mtx_threads));
|
||||
|
||||
/* We detach ourselves so nobody needs to join to us */
|
||||
pthread_detach(pthread_self());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to start a Zephyr thread as a POSIX thread:
|
||||
* It will block the thread until a arch_swap() is called for it
|
||||
*
|
||||
* Spawned from posix_new_thread() below
|
||||
*/
|
||||
static void *posix_thread_starter(void *arg)
|
||||
{
|
||||
int thread_idx = (intptr_t)arg;
|
||||
|
||||
PC_DEBUG("Thread [%i] %i: %s: Starting\n",
|
||||
threads_table[thread_idx].thead_cnt,
|
||||
thread_idx,
|
||||
__func__);
|
||||
|
||||
/*
|
||||
* We block until all other running threads reach the while loop
|
||||
* in posix_wait_until_allowed() and they release the mutex
|
||||
*/
|
||||
PC_SAFE_CALL(pthread_mutex_lock(&mtx_threads));
|
||||
|
||||
/*
|
||||
* The program may have been finished before this thread ever got to run
|
||||
*/
|
||||
/* LCOV_EXCL_START */ /* See Note1 */
|
||||
if (!threads_table) {
|
||||
posix_cleanup_handler(arg);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
||||
pthread_cleanup_push(posix_cleanup_handler, arg);
|
||||
|
||||
PC_DEBUG("Thread [%i] %i: %s: After start mutex (hav mut)\n",
|
||||
threads_table[thread_idx].thead_cnt,
|
||||
thread_idx,
|
||||
__func__);
|
||||
|
||||
/*
|
||||
* The thread would try to execute immediately, so we block it
|
||||
* until allowed
|
||||
*/
|
||||
posix_wait_until_allowed(thread_idx);
|
||||
|
||||
posix_thread_status_t *ptr = threads_table[thread_idx].t_status;
|
||||
|
||||
posix_arch_thread_entry(ptr);
|
||||
|
||||
/*
|
||||
* We only reach this point if the thread actually returns which should
|
||||
* not happen. But we handle it gracefully just in case
|
||||
*/
|
||||
/* LCOV_EXCL_START */
|
||||
posix_print_trace(PREFIX"Thread [%i] %i [%lu] ended!?!\n",
|
||||
threads_table[thread_idx].thead_cnt,
|
||||
thread_idx,
|
||||
pthread_self());
|
||||
|
||||
|
||||
threads_table[thread_idx].running = false;
|
||||
threads_table[thread_idx].state = FAILED;
|
||||
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
return NULL;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first free entry index in the threads table
|
||||
*/
|
||||
static int ttable_get_empty_slot(void)
|
||||
{
|
||||
|
||||
for (int i = 0; i < threads_table_size; i++) {
|
||||
if ((threads_table[i].state == NOTUSED)
|
||||
|| (PC_REUSE_ABORTED_ENTRIES
|
||||
&& (threads_table[i].state == ABORTED))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* else, we run out table without finding an index
|
||||
* => we expand the table
|
||||
*/
|
||||
|
||||
threads_table = realloc(threads_table,
|
||||
(threads_table_size + PC_ALLOC_CHUNK_SIZE)
|
||||
* sizeof(struct threads_table_el));
|
||||
if (threads_table == NULL) { /* LCOV_EXCL_BR_LINE */
|
||||
posix_print_error_and_exit(NO_MEM_ERR); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
/* Clear new piece of table */
|
||||
(void)memset(&threads_table[threads_table_size], 0,
|
||||
PC_ALLOC_CHUNK_SIZE * sizeof(struct threads_table_el));
|
||||
|
||||
threads_table_size += PC_ALLOC_CHUNK_SIZE;
|
||||
|
||||
/* The first newly created entry is good: */
|
||||
return threads_table_size - PC_ALLOC_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from arch_new_thread(),
|
||||
* Create a new POSIX thread for the new Zephyr thread.
|
||||
* arch_new_thread() picks from the kernel structures what it is that we need
|
||||
* to call with what parameters
|
||||
*/
|
||||
int posix_new_thread(void *ptr)
|
||||
{
|
||||
int t_slot;
|
||||
|
||||
t_slot = ttable_get_empty_slot();
|
||||
threads_table[t_slot].state = USED;
|
||||
threads_table[t_slot].running = false;
|
||||
threads_table[t_slot].thead_cnt = thread_create_count++;
|
||||
threads_table[t_slot].t_status = ptr;
|
||||
|
||||
/*
|
||||
* Note: If you are here due to a valgrind reported memory leak in
|
||||
* pthread_create() please use the provided valgrind.supp suppression file.
|
||||
*/
|
||||
PC_SAFE_CALL(pthread_create(&threads_table[t_slot].thread,
|
||||
NULL,
|
||||
posix_thread_starter,
|
||||
(void *)(intptr_t)t_slot));
|
||||
|
||||
PC_DEBUG("%s created thread [%i] %i [%lu]\n",
|
||||
__func__,
|
||||
threads_table[t_slot].thead_cnt,
|
||||
t_slot,
|
||||
threads_table[t_slot].thread);
|
||||
|
||||
return t_slot;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the posix architecture
|
||||
*
|
||||
* Prepare whatever needs to be prepared to be able to start threads
|
||||
*/
|
||||
void posix_arch_init(void)
|
||||
{
|
||||
thread_create_count = 0;
|
||||
|
||||
currently_allowed_thread = -1;
|
||||
|
||||
threads_table = calloc(PC_ALLOC_CHUNK_SIZE,
|
||||
sizeof(struct threads_table_el));
|
||||
if (threads_table == NULL) { /* LCOV_EXCL_BR_LINE */
|
||||
posix_print_error_and_exit(NO_MEM_ERR); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
threads_table_size = PC_ALLOC_CHUNK_SIZE;
|
||||
|
||||
|
||||
PC_SAFE_CALL(pthread_mutex_lock(&mtx_threads));
|
||||
}
|
||||
|
||||
/*
|
||||
* Free any allocated memory by the posix core and clean up.
|
||||
* Note that this function cannot be called from a SW thread
|
||||
* (the CPU is assumed halted. Otherwise we will cancel ourselves)
|
||||
*
|
||||
* This function cannot guarantee the threads will be cancelled before the HW
|
||||
* thread exists. The only way to do that, would be to wait for each of them in
|
||||
* a join (without detaching them, but that could lead to locks in some
|
||||
* convoluted cases. As a call to this function can come from an ASSERT or other
|
||||
* error termination, we better do not assume things are working fine.
|
||||
* => we prefer the supposed memory leak report from valgrind, and ensure we
|
||||
* will not hang
|
||||
*/
|
||||
void posix_arch_clean_up(void)
|
||||
{
|
||||
|
||||
if (!threads_table) { /* LCOV_EXCL_BR_LINE */
|
||||
return; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
terminate = true;
|
||||
|
||||
#if (PC_ENABLE_CANCEL)
|
||||
for (int i = 0; i < threads_table_size; i++) {
|
||||
if (threads_table[i].state != USED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* LCOV_EXCL_START */
|
||||
if (pthread_cancel(threads_table[i].thread)) {
|
||||
posix_print_warning(
|
||||
PREFIX"cleanup: could not stop thread %i\n",
|
||||
i);
|
||||
}
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#endif
|
||||
|
||||
free(threads_table);
|
||||
threads_table = NULL;
|
||||
}
|
||||
|
||||
void posix_abort_thread(int thread_idx)
|
||||
{
|
||||
if (thread_idx == currently_allowed_thread) {
|
||||
PC_DEBUG("Thread [%i] %i: %s Marked myself "
|
||||
"as aborting\n",
|
||||
threads_table[thread_idx].thead_cnt,
|
||||
thread_idx,
|
||||
__func__);
|
||||
} else {
|
||||
if (threads_table[thread_idx].state != USED) { /* LCOV_EXCL_BR_LINE */
|
||||
/* The thread may have been already aborted before */
|
||||
return; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
PC_DEBUG("Aborting not scheduled thread [%i] %i\n",
|
||||
threads_table[thread_idx].thead_cnt,
|
||||
thread_idx);
|
||||
}
|
||||
|
||||
threads_table[thread_idx].state = ABORTING;
|
||||
/*
|
||||
* Note: the native thread will linger in RAM until it catches the
|
||||
* mutex or awakes on the condition.
|
||||
* Note that even if we would pthread_cancel() the thread here, that
|
||||
* would be the case, but with a pthread_cancel() the mutex state would
|
||||
* be uncontrolled
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
int posix_arch_get_unique_thread_id(int thread_idx)
|
||||
{
|
||||
return threads_table[thread_idx].thead_cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notes about coverage:
|
||||
*
|
||||
* Note1:
|
||||
*
|
||||
* This condition will only be triggered in very unlikely cases
|
||||
* (once every few full regression runs).
|
||||
* It is therefore excluded from the coverage report to avoid confusing
|
||||
* developers.
|
||||
*
|
||||
* Background: This arch creates a pthread as soon as the Zephyr kernel creates
|
||||
* a Zephyr thread. A pthread creation is an asynchronous process handled by the
|
||||
* host kernel.
|
||||
*
|
||||
* This architecture normally keeps only 1 thread executing at a time.
|
||||
* But part of the pre-initialization during creation of a new thread
|
||||
* and some cleanup at the tail of the thread termination are executed
|
||||
* in parallel to other threads.
|
||||
* That is, the execution of those code paths is a bit indeterministic.
|
||||
*
|
||||
* Only when the Zephyr kernel attempts to swap to a new thread does this
|
||||
* architecture need to wait until its pthread is ready and initialized
|
||||
* (has reached posix_wait_until_allowed())
|
||||
*
|
||||
* In some cases (tests) threads are created which are never actually needed
|
||||
* (typically the idle thread). That means the test may finish before this
|
||||
* thread's underlying pthread has reached posix_wait_until_allowed().
|
||||
*
|
||||
* In this unlikely cases the initialization or cleanup of the thread follows
|
||||
* non-typical code paths.
|
||||
* This code paths are there to ensure things work always, no matter
|
||||
* the load of the host. Without them, very rare & mysterious segfault crashes
|
||||
* would occur.
|
||||
* But as they are very atypical and only triggered with some host loads,
|
||||
* they will be covered in the coverage reports only rarely.
|
||||
*
|
||||
* Note2:
|
||||
*
|
||||
* Some other code will never or only very rarely trigger and is therefore
|
||||
* excluded with LCOV_EXCL_LINE
|
||||
*
|
||||
*
|
||||
* Notes about (memory) cleanup:
|
||||
*
|
||||
* Note.c1:
|
||||
*
|
||||
* In some very rare cases in very loaded machines, a race in the glibc pthread_cancel()
|
||||
* seems to be triggered.
|
||||
* In this, the cancelled thread cleanup overtakes the pthread_cancel() code, and frees the
|
||||
* pthread structure before pthread_cancel() has finished, resulting in a dereference into already
|
||||
* free'd memory, and therefore a segfault.
|
||||
* Calling pthread_cancel() during cleanup is not required beyond preventing a valgrind
|
||||
* memory leak report (all threads will be canceled immediately on exit).
|
||||
* Therefore we do not do this, to avoid this very rare crashes.
|
||||
*/
|
||||
@@ -30,6 +30,7 @@ config RISCV_GP
|
||||
config RISCV_ALWAYS_SWITCH_THROUGH_ECALL
|
||||
bool "Do not use mret outside a trap handler context"
|
||||
depends on MULTITHREADING
|
||||
depends on !RISCV_PMP
|
||||
help
|
||||
Use mret instruction only when in a trap handler.
|
||||
This is for RISC-V implementations that require every mret to be
|
||||
@@ -47,11 +48,10 @@ config RISCV_EXCEPTION_STACK_TRACE
|
||||
menu "RISCV Processor Options"
|
||||
|
||||
config INCLUDE_RESET_VECTOR
|
||||
bool "Jumps to __initialize directly"
|
||||
bool "Include Reset vector"
|
||||
help
|
||||
Select 'y' here to use the Zephyr provided default implementation that
|
||||
jumps to `__initialize` directly. Otherwise a SOC needs to provide its
|
||||
custom `__reset` routine.
|
||||
Include the reset vector stub, which initializes the stack and
|
||||
prepares for running C code.
|
||||
|
||||
config RISCV_PRIVILEGED
|
||||
bool
|
||||
|
||||
@@ -7,20 +7,16 @@
|
||||
#include <zephyr/irq.h>
|
||||
#include <zephyr/tracing/tracing.h>
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
void arch_cpu_idle(void)
|
||||
void __weak arch_cpu_idle(void)
|
||||
{
|
||||
sys_trace_idle();
|
||||
__asm__ volatile("wfi");
|
||||
irq_unlock(MSTATUS_IEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
void arch_cpu_atomic_idle(unsigned int key)
|
||||
void __weak arch_cpu_atomic_idle(unsigned int key)
|
||||
{
|
||||
sys_trace_idle();
|
||||
__asm__ volatile("wfi");
|
||||
irq_unlock(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -226,13 +226,6 @@ void _Fault(struct arch_esf *esf)
|
||||
unsigned int reason = K_ERR_CPU_EXCEPTION;
|
||||
|
||||
if (bad_stack_pointer(esf)) {
|
||||
#ifdef CONFIG_PMP_STACK_GUARD
|
||||
/*
|
||||
* Remove the thread's PMP setting to prevent triggering a stack
|
||||
* overflow error again due to the previous configuration.
|
||||
*/
|
||||
z_riscv_pmp_stackguard_disable();
|
||||
#endif /* CONFIG_PMP_STACK_GUARD */
|
||||
reason = K_ERR_STACK_CHK_FAIL;
|
||||
}
|
||||
|
||||
|
||||
@@ -347,21 +347,6 @@ no_fp: /* increment _current->arch.exception_depth */
|
||||
*/
|
||||
li t1, RISCV_EXC_ECALLU
|
||||
beq t0, t1, is_user_syscall
|
||||
|
||||
#ifdef CONFIG_PMP_STACK_GUARD
|
||||
/*
|
||||
* Determine if we come from user space. If so, reconfigure the PMP for
|
||||
* kernel mode stack guard.
|
||||
*/
|
||||
csrr t0, mstatus
|
||||
li t1, MSTATUS_MPP
|
||||
and t0, t0, t1
|
||||
bnez t0, 1f
|
||||
lr a0, ___cpu_t_current_OFFSET(s0)
|
||||
call z_riscv_pmp_stackguard_enable
|
||||
1:
|
||||
#endif /* CONFIG_PMP_STACK_GUARD */
|
||||
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
/*
|
||||
@@ -413,22 +398,6 @@ is_kernel_syscall:
|
||||
bne t0, t1, skip_schedule
|
||||
lr a0, __struct_arch_esf_a0_OFFSET(sp)
|
||||
lr a1, __struct_arch_esf_a1_OFFSET(sp)
|
||||
|
||||
#ifdef CONFIG_FPU_SHARING
|
||||
/*
|
||||
* When an ECALL is used for a context-switch, the current thread has
|
||||
* been updated to the next thread.
|
||||
* Add the exception_depth back to the previous thread.
|
||||
*/
|
||||
lb t1, _thread_offset_to_exception_depth(a0)
|
||||
add t1, t1, -1
|
||||
sb t1, _thread_offset_to_exception_depth(a0)
|
||||
|
||||
lb t1, _thread_offset_to_exception_depth(a1)
|
||||
add t1, t1, 1
|
||||
sb t1, _thread_offset_to_exception_depth(a1)
|
||||
#endif
|
||||
|
||||
j reschedule
|
||||
skip_schedule:
|
||||
#endif
|
||||
|
||||
@@ -204,34 +204,6 @@ static bool set_pmp_entry(unsigned int *index_p, uint8_t perm,
|
||||
return ok;
|
||||
}
|
||||
|
||||
static inline bool set_pmp_mprv_catchall(unsigned int *index_p,
|
||||
unsigned long *pmp_addr, unsigned long *pmp_cfg,
|
||||
unsigned int index_limit)
|
||||
{
|
||||
/*
|
||||
* We'll be using MPRV. Make a fallback entry with everything
|
||||
* accessible as if no PMP entries were matched which is otherwise
|
||||
* the default behavior for m-mode without MPRV.
|
||||
*/
|
||||
bool ok = set_pmp_entry(index_p, PMP_R | PMP_W | PMP_X,
|
||||
0, 0, pmp_addr, pmp_cfg, index_limit);
|
||||
|
||||
#ifdef CONFIG_QEMU_TARGET
|
||||
if (ok) {
|
||||
/*
|
||||
* Workaround: The above produced 0x1fffffff which is correct.
|
||||
* But there is a QEMU bug that prevents it from interpreting
|
||||
* this value correctly. Hardcode the special case used by
|
||||
* QEMU to bypass this bug for now. The QEMU fix is here:
|
||||
* https://lists.gnu.org/archive/html/qemu-devel/2022-04/msg00961.html
|
||||
*/
|
||||
pmp_addr[*index_p - 1] = -1L;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a range of PMP entries to corresponding PMP registers
|
||||
*
|
||||
@@ -348,8 +320,8 @@ static unsigned int global_pmp_end_index;
|
||||
*/
|
||||
void z_riscv_pmp_init(void)
|
||||
{
|
||||
unsigned long pmp_addr[5];
|
||||
unsigned long pmp_cfg[2];
|
||||
unsigned long pmp_addr[4];
|
||||
unsigned long pmp_cfg[1];
|
||||
unsigned int index = 0;
|
||||
|
||||
/* The read-only area is always there for every mode */
|
||||
@@ -379,28 +351,10 @@ void z_riscv_pmp_init(void)
|
||||
(uintptr_t)z_interrupt_stacks[_current_cpu->id],
|
||||
Z_RISCV_STACK_GUARD_SIZE,
|
||||
pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
||||
|
||||
/*
|
||||
* This early, the kernel init code uses the IRQ stack and we want to
|
||||
* safeguard it as soon as possible. But we need a temporary default
|
||||
* "catch all" PMP entry for MPRV to work. Later on, this entry will
|
||||
* be set for each thread by z_riscv_pmp_stackguard_prepare().
|
||||
*/
|
||||
set_pmp_mprv_catchall(&index, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
||||
|
||||
/* Write those entries to PMP regs. */
|
||||
write_pmp_entries(0, index, true, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
||||
|
||||
/* Activate our non-locked PMP entries for m-mode */
|
||||
csr_set(mstatus, MSTATUS_MPRV);
|
||||
|
||||
/* And forget about that last entry as we won't need it later */
|
||||
index--;
|
||||
#else
|
||||
/* Write those entries to PMP regs. */
|
||||
write_pmp_entries(0, index, true, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
||||
#endif
|
||||
|
||||
write_pmp_entries(0, index, true, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#ifdef CONFIG_PMP_STACK_GUARD
|
||||
/*
|
||||
@@ -419,7 +373,6 @@ void z_riscv_pmp_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
__ASSERT(index <= PMPCFG_STRIDE, "provision for one global word only");
|
||||
global_pmp_cfg[0] = pmp_cfg[0];
|
||||
global_pmp_last_addr = pmp_addr[index - 1];
|
||||
global_pmp_end_index = index;
|
||||
@@ -476,7 +429,24 @@ void z_riscv_pmp_stackguard_prepare(struct k_thread *thread)
|
||||
set_pmp_entry(&index, PMP_NONE,
|
||||
stack_bottom, Z_RISCV_STACK_GUARD_SIZE,
|
||||
PMP_M_MODE(thread));
|
||||
set_pmp_mprv_catchall(&index, PMP_M_MODE(thread));
|
||||
|
||||
/*
|
||||
* We'll be using MPRV. Make a fallback entry with everything
|
||||
* accessible as if no PMP entries were matched which is otherwise
|
||||
* the default behavior for m-mode without MPRV.
|
||||
*/
|
||||
set_pmp_entry(&index, PMP_R | PMP_W | PMP_X,
|
||||
0, 0, PMP_M_MODE(thread));
|
||||
#ifdef CONFIG_QEMU_TARGET
|
||||
/*
|
||||
* Workaround: The above produced 0x1fffffff which is correct.
|
||||
* But there is a QEMU bug that prevents it from interpreting this
|
||||
* value correctly. Hardcode the special case used by QEMU to
|
||||
* bypass this bug for now. The QEMU fix is here:
|
||||
* https://lists.gnu.org/archive/html/qemu-devel/2022-04/msg00961.html
|
||||
*/
|
||||
thread->arch.m_mode_pmpaddr_regs[index-1] = -1L;
|
||||
#endif
|
||||
|
||||
/* remember how many entries we use */
|
||||
thread->arch.m_mode_pmp_end_index = index;
|
||||
@@ -511,37 +481,6 @@ void z_riscv_pmp_stackguard_enable(struct k_thread *thread)
|
||||
csr_set(mstatus, MSTATUS_MPRV);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove PMP stackguard content to actual PMP registers
|
||||
*/
|
||||
void z_riscv_pmp_stackguard_disable(void)
|
||||
{
|
||||
|
||||
unsigned long pmp_addr[PMP_M_MODE_SLOTS];
|
||||
unsigned long pmp_cfg[PMP_M_MODE_SLOTS / sizeof(unsigned long)];
|
||||
unsigned int index = global_pmp_end_index;
|
||||
|
||||
/* Retrieve the pmpaddr value matching the last global PMP slot. */
|
||||
pmp_addr[global_pmp_end_index - 1] = global_pmp_last_addr;
|
||||
|
||||
/* Disable (non-locked) PMP entries for m-mode while we update them. */
|
||||
csr_clear(mstatus, MSTATUS_MPRV);
|
||||
|
||||
/*
|
||||
* Set a temporary default "catch all" PMP entry for MPRV to work,
|
||||
* except for the global locked entries.
|
||||
*/
|
||||
set_pmp_mprv_catchall(&index, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
||||
|
||||
/* Write "catch all" entry and clear unlocked entries to PMP regs. */
|
||||
write_pmp_entries(global_pmp_end_index, index,
|
||||
true, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
||||
|
||||
if (PMP_DEBUG_DUMP) {
|
||||
dump_pmp_regs("catch all register dump");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PMP_STACK_GUARD */
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
|
||||
@@ -58,12 +58,12 @@ static inline bool in_user_thread_stack_bound(uintptr_t addr, const struct k_thr
|
||||
|
||||
/* See: zephyr/include/zephyr/arch/riscv/arch.h */
|
||||
if (IS_ENABLED(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT)) {
|
||||
start = thread->arch.priv_stack_start + Z_RISCV_STACK_GUARD_SIZE;
|
||||
start = thread->arch.priv_stack_start - CONFIG_PRIVILEGED_STACK_SIZE;
|
||||
end = thread->arch.priv_stack_start;
|
||||
} else {
|
||||
start = thread->stack_info.start - CONFIG_PRIVILEGED_STACK_SIZE;
|
||||
end = thread->stack_info.start;
|
||||
}
|
||||
end = Z_STACK_PTR_ALIGN(thread->arch.priv_stack_start + K_KERNEL_STACK_RESERVED +
|
||||
CONFIG_PRIVILEGED_STACK_SIZE);
|
||||
|
||||
return (addr >= start) && (addr < end);
|
||||
}
|
||||
@@ -90,10 +90,7 @@ static bool in_stack_bound(uintptr_t addr, const struct k_thread *const thread,
|
||||
static bool in_fatal_stack_bound(uintptr_t addr, const struct k_thread *const thread,
|
||||
const struct arch_esf *esf)
|
||||
{
|
||||
const uintptr_t align =
|
||||
COND_CODE_1(CONFIG_FRAME_POINTER, (ARCH_STACK_PTR_ALIGN), (sizeof(uintptr_t)));
|
||||
|
||||
if (!IS_ALIGNED(addr, align)) {
|
||||
if (!IS_ALIGNED(addr, sizeof(uintptr_t))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -137,53 +134,22 @@ static void walk_stackframe(stack_trace_callback_fn cb, void *cookie, const stru
|
||||
ra = csf->ra;
|
||||
}
|
||||
|
||||
for (int i = 0; (i < MAX_STACK_FRAMES) && vrfy(fp, thread, esf) && (fp > last_fp); i++) {
|
||||
if (in_text_region(ra) && !cb(cookie, ra)) {
|
||||
break;
|
||||
}
|
||||
last_fp = fp;
|
||||
|
||||
/* Unwind to the previous frame */
|
||||
frame = (struct stackframe *)fp - 1;
|
||||
|
||||
if ((i == 0) && (esf != NULL)) {
|
||||
/* Print `esf->ra` if we are at the top of the stack */
|
||||
if (in_text_region(esf->ra) && !cb(cookie, esf->ra)) {
|
||||
for (int i = 0; (i < MAX_STACK_FRAMES) && vrfy(fp, thread, esf) && (fp > last_fp);) {
|
||||
if (in_text_region(ra)) {
|
||||
if (!cb(cookie, ra)) {
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* For the first stack frame, the `ra` is not stored in the frame if the
|
||||
* preempted function doesn't call any other function, we can observe:
|
||||
*
|
||||
* .-------------.
|
||||
* frame[0]->fp ---> | frame[0] fp |
|
||||
* :-------------:
|
||||
* frame[0]->ra ---> | frame[1] fp |
|
||||
* | frame[1] ra |
|
||||
* :~~~~~~~~~~~~~:
|
||||
* | frame[N] fp |
|
||||
*
|
||||
* Instead of:
|
||||
*
|
||||
* .-------------.
|
||||
* frame[0]->fp ---> | frame[0] fp |
|
||||
* frame[0]->ra ---> | frame[1] ra |
|
||||
* :-------------:
|
||||
* | frame[1] fp |
|
||||
* | frame[1] ra |
|
||||
* :~~~~~~~~~~~~~:
|
||||
* | frame[N] fp |
|
||||
*
|
||||
* Check if `frame->ra` actually points to a `fp`, and adjust accordingly
|
||||
/*
|
||||
* Increment the iterator only if `ra` is within the text region to get the
|
||||
* most out of it
|
||||
*/
|
||||
if (vrfy(frame->ra, thread, esf)) {
|
||||
fp = frame->ra;
|
||||
frame = (struct stackframe *)fp;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
fp = frame->fp;
|
||||
last_fp = fp;
|
||||
/* Unwind to the previous frame */
|
||||
frame = (struct stackframe *)fp - 1;
|
||||
ra = frame->ra;
|
||||
fp = frame->fp;
|
||||
}
|
||||
}
|
||||
#else /* !CONFIG_FRAME_POINTER */
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
void z_riscv_pmp_init(void);
|
||||
void z_riscv_pmp_stackguard_prepare(struct k_thread *thread);
|
||||
void z_riscv_pmp_stackguard_enable(struct k_thread *thread);
|
||||
void z_riscv_pmp_stackguard_disable(void);
|
||||
void z_riscv_pmp_usermode_init(struct k_thread *thread);
|
||||
void z_riscv_pmp_usermode_prepare(struct k_thread *thread);
|
||||
void z_riscv_pmp_usermode_enable(struct k_thread *thread);
|
||||
|
||||
@@ -205,7 +205,7 @@ config MAX_IRQ_LINES
|
||||
config IRQ_OFFLOAD_VECTOR
|
||||
int "IDT vector to use for IRQ offload"
|
||||
default 33
|
||||
range 32 $(UINT8_MAX)
|
||||
range 32 255
|
||||
depends on IRQ_OFFLOAD
|
||||
|
||||
config PIC_DISABLE
|
||||
|
||||
@@ -42,13 +42,13 @@ config X86_EXCEPTION_STACK_TRACE
|
||||
config SCHED_IPI_VECTOR
|
||||
int "IDT vector to use for scheduler IPI"
|
||||
default 34
|
||||
range 33 $(UINT8_MAX)
|
||||
range 33 255
|
||||
depends on SMP
|
||||
|
||||
config TLB_IPI_VECTOR
|
||||
int "IDT vector to use for TLB shootdown IPI"
|
||||
default 35
|
||||
range 33 $(UINT8_MAX)
|
||||
range 33 255
|
||||
depends on SMP
|
||||
|
||||
# We should really only have to provide one of the following two values,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <zephyr/tracing/tracing.h>
|
||||
#include <zephyr/arch/cpu.h>
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
__pinned_func
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
@@ -16,9 +15,7 @@ void arch_cpu_idle(void)
|
||||
"sti\n\t"
|
||||
"hlt\n\t");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
__pinned_func
|
||||
void arch_cpu_atomic_idle(unsigned int key)
|
||||
{
|
||||
@@ -45,4 +42,3 @@ void arch_cpu_atomic_idle(unsigned int key)
|
||||
__asm__ volatile("cli");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -112,12 +112,11 @@ SECTION_FUNC(PINNED_TEXT, _interrupt_enter)
|
||||
* EAX = isr_param, EDX = isr
|
||||
*/
|
||||
|
||||
/* Push EBP as we will use it for scratch space.
|
||||
* Also it helps in stack unwinding
|
||||
/* Push EDI as we will use it for scratch space.
|
||||
* Rest of the callee-saved regs get saved by invocation of C
|
||||
* functions (isr handler, arch_swap(), etc)
|
||||
*/
|
||||
pushl %ebp
|
||||
pushl %edi
|
||||
|
||||
/* load %ecx with &_kernel */
|
||||
|
||||
@@ -132,17 +131,17 @@ SECTION_FUNC(PINNED_TEXT, _interrupt_enter)
|
||||
jne alreadyOnIntStack
|
||||
|
||||
/*
|
||||
* switch to base of the interrupt stack: save esp in ebp, then load
|
||||
* switch to base of the interrupt stack: save esp in edi, then load
|
||||
* irq_stack pointer
|
||||
*/
|
||||
|
||||
movl %esp, %ebp
|
||||
movl %esp, %edi
|
||||
movl _kernel_offset_to_irq_stack(%ecx), %esp
|
||||
|
||||
|
||||
/* save thread's stack pointer onto base of interrupt stack */
|
||||
|
||||
pushl %ebp /* Save stack pointer */
|
||||
pushl %edi /* Save stack pointer */
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
cmpl $0, _kernel_offset_to_idle(%ecx)
|
||||
@@ -266,7 +265,7 @@ alreadyOnIntStack:
|
||||
#endif /* CONFIG_LAZY_FPU_SHARING */
|
||||
|
||||
/* Restore volatile registers and return to the interrupted thread */
|
||||
popl %ebp
|
||||
popl %edi
|
||||
popl %ecx
|
||||
popl %edx
|
||||
popl %eax
|
||||
@@ -299,7 +298,7 @@ noReschedule:
|
||||
*/
|
||||
|
||||
nestedInterrupt:
|
||||
popl %ebp
|
||||
popl %edi
|
||||
popl %ecx /* pop volatile registers in reverse order */
|
||||
popl %edx
|
||||
popl %eax
|
||||
|
||||
@@ -100,8 +100,8 @@ void z_x86_irq_connect_on_vector(unsigned int irq,
|
||||
*/
|
||||
|
||||
int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
|
||||
void (*routine)(const void *parameter),
|
||||
const void *parameter, uint32_t flags)
|
||||
void (*func)(const void *arg),
|
||||
const void *arg, uint32_t flags)
|
||||
{
|
||||
uint32_t key;
|
||||
int vector;
|
||||
@@ -124,7 +124,7 @@ int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
|
||||
#endif /* CONFIG_INTEL_VTD_ICTL */
|
||||
|
||||
z_irq_controller_irq_config(vector, irq, flags);
|
||||
z_x86_irq_connect_on_vector(irq, vector, routine, parameter);
|
||||
z_x86_irq_connect_on_vector(irq, vector, func, arg);
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
@@ -12,7 +12,6 @@ zephyr_library_sources(
|
||||
irq_manage.c
|
||||
thread.c
|
||||
vector_handlers.c
|
||||
prep_c.c
|
||||
)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_XTENSA_USE_CORE_CRT1 crt1.S)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <zephyr/toolchain.h>
|
||||
#include <zephyr/tracing/tracing.h>
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
|
||||
#ifndef CONFIG_ARCH_CPU_IDLE_CUSTOM
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
sys_trace_idle();
|
||||
@@ -14,7 +14,6 @@ void arch_cpu_idle(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
|
||||
void arch_cpu_atomic_idle(unsigned int key)
|
||||
{
|
||||
sys_trace_idle();
|
||||
@@ -22,4 +21,3 @@ void arch_cpu_atomic_idle(unsigned int key)
|
||||
"wsr.ps %0\n\t"
|
||||
"rsync" :: "a"(key));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Control arrives here at _start from the reset vector.
|
||||
* Control arrives here at _start from the reset vector or from crt0-app.S.
|
||||
*/
|
||||
|
||||
#include <xtensa/coreasm.h>
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
.global __start
|
||||
.type z_prep_c, @function
|
||||
.type z_cstart, @function
|
||||
|
||||
|
||||
/* Macros to abstract away ABI differences */
|
||||
@@ -52,7 +52,7 @@ _start:
|
||||
/*
|
||||
* _start is typically NOT at the beginning of the text segment --
|
||||
* it is always called from either the reset vector (__start) or other
|
||||
* code that does equivalent initialization.
|
||||
* code that does equivalent initialization (such as crt0-app.S).
|
||||
*
|
||||
* Assumptions on entry to _start:
|
||||
* - low (level-one) and medium priority interrupts are disabled
|
||||
@@ -189,6 +189,6 @@ _start:
|
||||
#endif /* !XCHAL_HAVE_BOOTLOADER */
|
||||
|
||||
/* Enter C domain, never returns from here */
|
||||
CALL z_prep_c
|
||||
CALL z_cstart
|
||||
|
||||
.size _start, . - _start
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <zephyr/kernel.h>
|
||||
#include <kernel_internal.h>
|
||||
|
||||
extern FUNC_NORETURN void z_cstart(void);
|
||||
|
||||
/* defined by the SoC in case of CONFIG_SOC_HAS_RUNTIME_NUM_CPUS=y */
|
||||
extern void soc_num_cpus_init(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Prepare to and run C code
|
||||
*
|
||||
* This routine prepares for the execution of and runs C code.
|
||||
*
|
||||
*/
|
||||
void z_prep_c(void)
|
||||
{
|
||||
#if CONFIG_SOC_HAS_RUNTIME_NUM_CPUS
|
||||
soc_num_cpus_init();
|
||||
#endif
|
||||
|
||||
_cpu_t *cpu0 = &_kernel.cpus[0];
|
||||
|
||||
#ifdef CONFIG_KERNEL_COHERENCE
|
||||
/* Make sure we don't have live data for unexpected cached
|
||||
* regions due to boot firmware
|
||||
*/
|
||||
sys_cache_data_flush_and_invd_all();
|
||||
|
||||
/* Our cache top stash location might have junk in it from a
|
||||
* pre-boot environment. Must be zero or valid!
|
||||
*/
|
||||
XTENSA_WSR(ZSR_FLUSH_STR, 0);
|
||||
#endif
|
||||
|
||||
cpu0->nested = 0;
|
||||
|
||||
/* The asm2 scheme keeps the kernel pointer in a scratch SR
|
||||
* (see zsr.h for generation specifics) for easy access. That
|
||||
* saves 4 bytes of immediate value to store the address when
|
||||
* compared to the legacy scheme. But in SMP this record is a
|
||||
* per-CPU thing and having it stored in a SR already is a big
|
||||
* win.
|
||||
*/
|
||||
XTENSA_WSR(ZSR_CPU_STR, cpu0);
|
||||
|
||||
#ifdef CONFIG_INIT_STACKS
|
||||
char *stack_start = K_KERNEL_STACK_BUFFER(z_interrupt_stacks[0]);
|
||||
size_t stack_sz = K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0]);
|
||||
char *stack_end = stack_start + stack_sz;
|
||||
|
||||
uint32_t sp;
|
||||
|
||||
__asm__ volatile("mov %0, sp" : "=a"(sp));
|
||||
|
||||
/* Only clear the interrupt stack if the current stack pointer
|
||||
* is not within the interrupt stack. Or else we would be
|
||||
* wiping the in-use stack.
|
||||
*/
|
||||
if (((uintptr_t)sp < (uintptr_t)stack_start) ||
|
||||
((uintptr_t)sp >= (uintptr_t)stack_end)) {
|
||||
memset(stack_start, 0xAA, stack_sz);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XTENSA_MMU
|
||||
xtensa_mmu_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XTENSA_MPU
|
||||
xtensa_mpu_init();
|
||||
#endif
|
||||
z_cstart();
|
||||
CODE_UNREACHABLE;
|
||||
}
|
||||
@@ -267,12 +267,6 @@ static void map_memory(const uint32_t start, const uint32_t end,
|
||||
static void xtensa_init_page_tables(void)
|
||||
{
|
||||
volatile uint8_t entry;
|
||||
static bool already_inited;
|
||||
|
||||
if (already_inited) {
|
||||
return;
|
||||
}
|
||||
already_inited = true;
|
||||
|
||||
init_page_table(xtensa_kernel_ptables, XTENSA_L1_PAGE_TABLE_ENTRIES);
|
||||
atomic_set_bit(l1_page_table_track, 0);
|
||||
@@ -311,17 +305,18 @@ __weak void arch_xtensa_mmu_post_init(bool is_core0)
|
||||
|
||||
void xtensa_mmu_init(void)
|
||||
{
|
||||
xtensa_init_page_tables();
|
||||
if (_current_cpu->id == 0) {
|
||||
/* This is normally done via arch_kernel_init() inside z_cstart().
|
||||
* However, before that is called, we go through the sys_init of
|
||||
* INIT_LEVEL_EARLY, which is going to result in TLB misses.
|
||||
* So setup whatever necessary so the exception handler can work
|
||||
* properly.
|
||||
*/
|
||||
xtensa_init_page_tables();
|
||||
}
|
||||
|
||||
xtensa_init_paging(xtensa_kernel_ptables);
|
||||
|
||||
/*
|
||||
* This is used to determine whether we are faulting inside double
|
||||
* exception if this is not zero. Sometimes SoC starts with this not
|
||||
* being set to zero. So clear it during boot.
|
||||
*/
|
||||
XTENSA_WSR(ZSR_DEPC_SAVE_STR, 0);
|
||||
|
||||
arch_xtensa_mmu_post_init(_current_cpu->id == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -363,13 +363,9 @@ void *xtensa_excint1_c(void *esf)
|
||||
|
||||
switch (cause) {
|
||||
case EXCCAUSE_LEVEL1_INTERRUPT:
|
||||
#ifdef CONFIG_XTENSA_MMU
|
||||
if (!is_dblexc) {
|
||||
return xtensa_int1_c(interrupted_stack);
|
||||
}
|
||||
#else
|
||||
return xtensa_int1_c(interrupted_stack);
|
||||
#endif /* CONFIG_XTENSA_MMU */
|
||||
break;
|
||||
#ifndef CONFIG_USERSPACE
|
||||
/* Syscalls are handled earlier in assembly if MMU is enabled.
|
||||
|
||||
@@ -25,7 +25,57 @@ K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,
|
||||
|
||||
static ALWAYS_INLINE void arch_kernel_init(void)
|
||||
{
|
||||
_cpu_t *cpu0 = &_kernel.cpus[0];
|
||||
|
||||
#ifdef CONFIG_KERNEL_COHERENCE
|
||||
/* Make sure we don't have live data for unexpected cached
|
||||
* regions due to boot firmware
|
||||
*/
|
||||
sys_cache_data_flush_and_invd_all();
|
||||
|
||||
/* Our cache top stash location might have junk in it from a
|
||||
* pre-boot environment. Must be zero or valid!
|
||||
*/
|
||||
XTENSA_WSR(ZSR_FLUSH_STR, 0);
|
||||
#endif
|
||||
|
||||
cpu0->nested = 0;
|
||||
|
||||
/* The asm2 scheme keeps the kernel pointer in a scratch SR
|
||||
* (see zsr.h for generation specifics) for easy access. That
|
||||
* saves 4 bytes of immediate value to store the address when
|
||||
* compared to the legacy scheme. But in SMP this record is a
|
||||
* per-CPU thing and having it stored in a SR already is a big
|
||||
* win.
|
||||
*/
|
||||
XTENSA_WSR(ZSR_CPU_STR, cpu0);
|
||||
|
||||
#ifdef CONFIG_INIT_STACKS
|
||||
char *stack_start = K_KERNEL_STACK_BUFFER(z_interrupt_stacks[0]);
|
||||
size_t stack_sz = K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0]);
|
||||
char *stack_end = stack_start + stack_sz;
|
||||
|
||||
uint32_t sp;
|
||||
|
||||
__asm__ volatile("mov %0, sp" : "=a"(sp));
|
||||
|
||||
/* Only clear the interrupt stack if the current stack pointer
|
||||
* is not within the interrupt stack. Or else we would be
|
||||
* wiping the in-use stack.
|
||||
*/
|
||||
if (((uintptr_t)sp < (uintptr_t)stack_start) ||
|
||||
((uintptr_t)sp >= (uintptr_t)stack_end)) {
|
||||
memset(stack_start, 0xAA, stack_sz);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XTENSA_MMU
|
||||
xtensa_mmu_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XTENSA_MPU
|
||||
xtensa_mpu_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void xtensa_switch(void *switch_to, void **switched_from);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Copyright 2022 Google LLC
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config HEAP_MEM_POOL_ADD_SIZE_BOARD
|
||||
int
|
||||
default 65535 if WIFI && BT
|
||||
default 51200 if WIFI
|
||||
default 40960 if BT
|
||||
default 4096
|
||||
@@ -1,5 +0,0 @@
|
||||
# Copyright 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_ESP32C3_042_OLED
|
||||
select SOC_ESP32C3_FX4
|
||||
@@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
choice BOOTLOADER
|
||||
default BOOTLOADER_MCUBOOT
|
||||
endchoice
|
||||
|
||||
choice BOOT_SIGNATURE_TYPE
|
||||
default BOOT_SIGNATURE_TYPE_NONE
|
||||
endchoice
|
||||
@@ -1,9 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*")
|
||||
set(OPENOCD OPENOCD-NOTFOUND)
|
||||
endif()
|
||||
find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH)
|
||||
|
||||
include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake)
|
||||
@@ -1,5 +0,0 @@
|
||||
board:
|
||||
name: esp32c3_042_oled
|
||||
vendor: 01space
|
||||
socs:
|
||||
- name: esp32c3
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 62 KiB |
@@ -1,172 +0,0 @@
|
||||
.. _01space_esp32c3_042_oled:
|
||||
|
||||
ESP32C3 0.42 OLED
|
||||
#################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
ESP32C3 0.42 OLED is a mini development board based on the `Espressif ESP32-C3`_
|
||||
RISC-V WiFi/Bluetooth dual-mode chip.
|
||||
|
||||
For more details see the `01space ESP32C3 0.42 OLED`_ Github repo.
|
||||
|
||||
.. figure:: img/esp32c3_042_oled.webp
|
||||
:align: center
|
||||
:alt: 01space ESP32C3 0.42 OLED
|
||||
|
||||
01space ESP32C3 0.42 OLED
|
||||
|
||||
Hardware
|
||||
********
|
||||
|
||||
This board is based on the ESP32-C3-FH4 with WiFi and BLE support.
|
||||
It features:
|
||||
|
||||
* RISC-V SoC @ 160MHz with 4MB flash and 400kB RAM
|
||||
* WS2812B RGB serial LED
|
||||
* 0.42-inch OLED over I2C
|
||||
* Qwiic I2C connector
|
||||
* One pushbutton
|
||||
* Onboard ceramic chip antenna
|
||||
* On-chip USB-UART converter
|
||||
|
||||
.. note::
|
||||
|
||||
The RGB led is not supported on this Zephyr board yet.
|
||||
|
||||
.. note::
|
||||
|
||||
The ESP32-C3 does not have native USB, it has an on-chip USB-serial converter
|
||||
instead.
|
||||
|
||||
Supported Features
|
||||
==================
|
||||
|
||||
The 01space ESP32C3 0.42 OLED board configuration supports the following hardware features:
|
||||
|
||||
+-----------+------------+------------------+
|
||||
| Interface | Controller | Driver/Component |
|
||||
+===========+============+==================+
|
||||
| PMP | on-chip | arch/riscv |
|
||||
+-----------+------------+------------------+
|
||||
| INTMTRX | on-chip | intc_esp32c3 |
|
||||
+-----------+------------+------------------+
|
||||
| PINMUX | on-chip | pinctrl_esp32 |
|
||||
+-----------+------------+------------------+
|
||||
| USB UART | on-chip | serial_esp32_usb |
|
||||
+-----------+------------+------------------+
|
||||
| GPIO | on-chip | gpio_esp32 |
|
||||
+-----------+------------+------------------+
|
||||
| UART | on-chip | uart_esp32 |
|
||||
+-----------+------------+------------------+
|
||||
| I2C | on-chip | i2c_esp32 |
|
||||
+-----------+------------+------------------+
|
||||
| SPI | on-chip | spi_esp32_spim |
|
||||
+-----------+------------+------------------+
|
||||
| RADIO | on-chip | Bluetooth |
|
||||
+-----------+------------+------------------+
|
||||
| DISPLAY | off-chip | display |
|
||||
+-----------+------------+------------------+
|
||||
|
||||
Connections and IOs
|
||||
===================
|
||||
|
||||
See the following image:
|
||||
|
||||
.. figure:: img/esp32c3_042_oled_pinout.webp
|
||||
:align: center
|
||||
:alt: 01space ESP32C3 0.42 OLED Pinout
|
||||
|
||||
01space ESP32C3 0.42 OLED Pinout
|
||||
|
||||
It also features a 0.42 inch OLED display, driven by a SSD1306-compatible chip.
|
||||
It is connected over I2C: SDA on GPIO5, SCL on GPIO6.
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
Espressif HAL requires WiFi and Bluetooth binary blobs. Run the command below to
|
||||
retrieve those files.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
west blobs fetch hal_espressif
|
||||
|
||||
.. note::
|
||||
|
||||
It is recommended running the command above after :file:`west update`.
|
||||
|
||||
Programming and Debugging
|
||||
*************************
|
||||
|
||||
Standalone application
|
||||
======================
|
||||
|
||||
The board can be loaded using a single binary image, without 2nd stage bootloader.
|
||||
It is the default option when building the application without additional configuration.
|
||||
|
||||
.. note::
|
||||
|
||||
This mode does not provide any security features nor OTA updates.
|
||||
|
||||
Use the following command to build a sample hello_world application:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/hello_world
|
||||
:board: esp32c3_042_oled
|
||||
:goals: build
|
||||
|
||||
Sysbuild
|
||||
========
|
||||
|
||||
:ref:`sysbuild` makes it possible to build and flash all necessary images needed to
|
||||
bootstrap the board.
|
||||
|
||||
By default, the ESP32 sysbuild configuration creates bootloader (MCUboot) and
|
||||
application images.
|
||||
|
||||
To build the sample application using sysbuild, use this command:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:tool: west
|
||||
:app: samples/hello_world
|
||||
:board: esp32c3_042_oled
|
||||
:goals: build
|
||||
:west-args: --sysbuild
|
||||
:compact:
|
||||
|
||||
Flashing
|
||||
========
|
||||
|
||||
For the :code:`Hello, world!` application, follow the instructions below.
|
||||
Assuming the board is connected to ``/dev/ttyACM0`` on Linux.
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/hello_world
|
||||
:board: esp32c3_042_oled
|
||||
:goals: flash
|
||||
:flash-args: --esp-device /dev/ttyACM0
|
||||
|
||||
Since the Zephyr console is by default on the ``usb_serial`` device, we use
|
||||
the espressif monitor utility to connect to the console.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ west espressif monitor -p /dev/ttyACM0
|
||||
|
||||
After the board has automatically reset and booted, you should see the following
|
||||
message in the monitor:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx *****
|
||||
Hello World! esp32c3_042_oled
|
||||
|
||||
References
|
||||
**********
|
||||
|
||||
.. target-notes::
|
||||
|
||||
.. _`Espressif ESP32-C3`: https://www.espressif.com/en/products/socs/esp32-c3
|
||||
.. _`01space ESP32C3 0.42 OLED`: https://github.com/01Space/ESP32-C3-0.42LCD
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/dt-bindings/pinctrl/esp-pinctrl-common.h>
|
||||
#include <dt-bindings/pinctrl/esp32c3-pinctrl.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/esp32c3-gpio-sigmap.h>
|
||||
|
||||
&pinctrl {
|
||||
uart1_default: uart1_default {
|
||||
group1 {
|
||||
pinmux = <UART1_TX_GPIO21>;
|
||||
output-high;
|
||||
};
|
||||
group2 {
|
||||
pinmux = <UART1_RX_GPIO20>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
spim2_default: spim2_default {
|
||||
group1 {
|
||||
pinmux = <SPIM2_MISO_GPIO8>,
|
||||
<SPIM2_SCLK_GPIO10>;
|
||||
};
|
||||
group2 {
|
||||
pinmux = <SPIM2_MOSI_GPIO7>;
|
||||
output-low;
|
||||
};
|
||||
};
|
||||
|
||||
i2c0_default: i2c0_default {
|
||||
group1 {
|
||||
pinmux = <I2C0_SDA_GPIO5>,
|
||||
<I2C0_SCL_GPIO6>;
|
||||
bias-pull-up;
|
||||
drive-open-drain;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
* Copyright 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <espressif/esp32c3/esp32c3_fx4.dtsi>
|
||||
#include "esp32c3_042_oled-pinctrl.dtsi"
|
||||
|
||||
/ {
|
||||
model = "01space ESP32C3 0.42 OLED";
|
||||
|
||||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,console = &usb_serial;
|
||||
zephyr,shell-uart = &usb_serial;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,code-partition = &slot0_partition;
|
||||
zephyr,canbus = &twai;
|
||||
zephyr,bt-hci = &esp32_bt_hci;
|
||||
zephyr,display = &eastrising_72x40;
|
||||
};
|
||||
|
||||
aliases {
|
||||
i2c-0 = &i2c0;
|
||||
watchdog0 = &wdt0;
|
||||
};
|
||||
|
||||
/* WS2812B LED connected to GPIO2 */
|
||||
};
|
||||
|
||||
/* Have to use uart1 as some tests are hardcoded for that DTS node :/ */
|
||||
&uart1 {
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
pinctrl-0 = <&uart1_default>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
pinctrl-0 = <&i2c0_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
eastrising_72x40: ssd1306@3c {
|
||||
compatible = "solomon,ssd1306fb";
|
||||
reg = <0x3c>;
|
||||
|
||||
width = <72>;
|
||||
height = <40>;
|
||||
|
||||
segment-offset = <28>;
|
||||
page-offset = <0>;
|
||||
display-offset = <0>;
|
||||
multiplex-ratio = <0x27>;
|
||||
prechargep = <0x22>;
|
||||
ready-time-ms = <10>;
|
||||
segment-remap;
|
||||
com-invdir;
|
||||
use-internal-iref;
|
||||
};
|
||||
};
|
||||
|
||||
&spi2 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
pinctrl-0 = <&spim2_default>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&usb_serial {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&trng0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wdt0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&timer0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&timer1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wifi {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&esp32_bt_hci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
boot_partition: partition@0 {
|
||||
label = "mcuboot";
|
||||
reg = <0x00000000 0x0000F000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
slot0_partition: partition@10000 {
|
||||
label = "image-0";
|
||||
reg = <0x00010000 0x00100000>;
|
||||
};
|
||||
|
||||
slot1_partition: partition@110000 {
|
||||
label = "image-1";
|
||||
reg = <0x00110000 0x00100000>;
|
||||
};
|
||||
|
||||
scratch_partition: partition@210000 {
|
||||
label = "image-scratch";
|
||||
reg = <0x00210000 0x00040000>;
|
||||
};
|
||||
|
||||
storage_partition: partition@250000 {
|
||||
label = "storage";
|
||||
reg = <0x00250000 0x00006000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
identifier: esp32c3_042_oled
|
||||
name: ESP32C3 0.42 OLED
|
||||
type: mcu
|
||||
arch: riscv
|
||||
toolchain:
|
||||
- zephyr
|
||||
supported:
|
||||
- display
|
||||
- gpio
|
||||
- i2c
|
||||
- spi
|
||||
- uart
|
||||
- watchdog
|
||||
testing:
|
||||
ignore_tags:
|
||||
- net
|
||||
- bluetooth
|
||||
vendor: 01space
|
||||
@@ -1,8 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_MAIN_STACK_SIZE=2048
|
||||
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_UART_CONSOLE=y
|
||||
CONFIG_GPIO=y
|
||||
@@ -1,6 +0,0 @@
|
||||
set ESP_RTOS none
|
||||
|
||||
source [find interface/esp_usb_jtag.cfg]
|
||||
|
||||
source [find target/esp32c3.cfg]
|
||||
adapter speed 5000
|
||||
@@ -1,10 +0,0 @@
|
||||
.. _boards-01space:
|
||||
|
||||
01space
|
||||
#######
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
**/*
|
||||
@@ -17,5 +17,3 @@ if(EXISTS ${BOARD_DIR}/CMakeLists.txt)
|
||||
|
||||
add_subdirectory(${BOARD_DIR} ${build_dir})
|
||||
endif()
|
||||
|
||||
add_subdirectory(shields)
|
||||
|
||||
@@ -37,8 +37,6 @@ config BOARD_DEPRECATED_RELEASE
|
||||
the Zephyr release that the board configuration will be removed.
|
||||
When set, any build for that board will generate a clearly visible
|
||||
deprecation warning.
|
||||
When adding this to a BOARD, remember to follow the instructions in
|
||||
https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated
|
||||
|
||||
config QEMU_TARGET
|
||||
bool
|
||||
|
||||
10
boards/adafruit/feather/Kconfig
Normal file
10
boards/adafruit/feather/Kconfig
Normal file
@@ -0,0 +1,10 @@
|
||||
# Adafruit Feather nRF52840 Express board configuration
|
||||
|
||||
# Copyright (c) 2020 Tobias Svehagen
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_ENABLE_DCDC
|
||||
bool "DCDC mode"
|
||||
select SOC_DCDC_NRF52X
|
||||
default y
|
||||
depends on BOARD_ADAFRUIT_FEATHER
|
||||
@@ -1,8 +1,7 @@
|
||||
# Adafruit Feather nRF52840 Express board configuration
|
||||
|
||||
# Copyright (c) 2020 Tobias Svehagen
|
||||
# Copyright (c) 2024 Jacob Winther
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_ADAFRUIT_FEATHER_NRF52840_SENSE
|
||||
config BOARD_ADAFRUIT_FEATHER
|
||||
select SOC_NRF52840_QIAA
|
||||
@@ -1,8 +1,11 @@
|
||||
# Adafruit Feather nRF52840 Express board configuration
|
||||
|
||||
# Copyright (c) 2020 Tobias Svehagen
|
||||
# Copyright (c) 2024 Jacob Winther
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_ADAFRUIT_FEATHER_NRF52840_EXPRESS
|
||||
select SOC_NRF52840_QIAA
|
||||
if BOARD_ADAFRUIT_FEATHER
|
||||
|
||||
config BT_CTLR
|
||||
default BT
|
||||
|
||||
endif # BOARD_ADAFRUIT_FEATHER
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Tobias Svehagen
|
||||
* Copyright (c) 2024 Jacob Winther
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,16 +11,25 @@
|
||||
#include <zephyr/dt-bindings/input/input-event-codes.h>
|
||||
|
||||
/ {
|
||||
model = "Adafruit Feather nRF52840 Express";
|
||||
compatible = "adafruit,feather-nrf52840";
|
||||
|
||||
chosen {
|
||||
zephyr,console = &uart0;
|
||||
zephyr,shell-uart = &uart0;
|
||||
zephyr,uart-mcumgr = &uart0;
|
||||
zephyr,bt-mon-uart = &uart0;
|
||||
zephyr,bt-c2h-uart = &uart0;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,code-partition = &slot0_partition;
|
||||
zephyr,ieee802154 = &ieee802154;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
led0: led_0 {
|
||||
gpios = <&gpio1 15 0>;
|
||||
label = "Red LED";
|
||||
};
|
||||
led1: led_1 {
|
||||
@@ -55,10 +63,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
®1 {
|
||||
regulator-initial-mode = <NRF5X_REG_MODE_DCDC>;
|
||||
};
|
||||
|
||||
&adc {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -115,7 +119,7 @@
|
||||
writeoc = "pp4o";
|
||||
readoc = "read4io";
|
||||
sck-frequency = <16000000>;
|
||||
jedec-id = [ c8 40 15 ];
|
||||
jedec-id = [c8 40 15];
|
||||
size = <16777216>;
|
||||
has-dpd;
|
||||
t-enter-dpd = <20000>;
|
||||
@@ -128,6 +132,43 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
boot_partition: partition@0 {
|
||||
label = "mcuboot";
|
||||
reg = <0x00000000 0x0000C000>;
|
||||
};
|
||||
slot0_partition: partition@c000 {
|
||||
label = "image-0";
|
||||
reg = <0x0000C000 0x00067000>;
|
||||
};
|
||||
slot1_partition: partition@73000 {
|
||||
label = "image-1";
|
||||
reg = <0x00073000 0x00067000>;
|
||||
};
|
||||
scratch_partition: partition@da000 {
|
||||
label = "image-scratch";
|
||||
reg = <0x000da000 0x0001e000>;
|
||||
};
|
||||
|
||||
/*
|
||||
* The flash starting at 0x000f8000 and ending at
|
||||
* 0x000fffff is reserved for use by the application.
|
||||
*/
|
||||
|
||||
/* Storage partition will be used by FCB/NFFS/NVS if enabled. */
|
||||
storage_partition: partition@f8000 {
|
||||
label = "storage";
|
||||
reg = <0x000f8000 0x00008000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
zephyr_udc0: &usbd {
|
||||
compatible = "nordic,nrf-usbd";
|
||||
status = "okay";
|
||||
@@ -1,4 +1,4 @@
|
||||
identifier: adafruit_feather_nrf52840_express
|
||||
identifier: adafruit_feather/nrf52840
|
||||
name: Adafruit Feather nRF52840 Express
|
||||
type: mcu
|
||||
arch: arm
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
board_runner_args(jlink "--device=nRF52840_xxAA" "--speed=4000")
|
||||
board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000")
|
||||
if(CONFIG_BOARD_ADAFRUIT_FEATHER_NRF52840_SENSE)
|
||||
include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake)
|
||||
endif()
|
||||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake)
|
||||
5
boards/adafruit/feather/board.yml
Normal file
5
boards/adafruit/feather/board.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
board:
|
||||
name: adafruit_feather
|
||||
vendor: adafruit
|
||||
socs:
|
||||
- name: nrf52840
|
||||
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
@@ -1,7 +1,7 @@
|
||||
.. _adafruit_feather_nrf52840:
|
||||
|
||||
Adafruit Feather nRF52840 (Express, Sense)
|
||||
##########################################
|
||||
Adafruit Feather nRF52840 Express
|
||||
#################################
|
||||
|
||||
Overview
|
||||
********
|
||||
@@ -25,19 +25,9 @@ nRF52840 ARM Cortex-M4F CPU and the following devices:
|
||||
* :abbr:`USB (Universal Serial Bus)`
|
||||
* :abbr:`WDT (Watchdog Timer)`
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Express
|
||||
|
||||
.. figure:: img/adafruit_feather_nrf52840_express.jpg
|
||||
:align: center
|
||||
:alt: Adafruit Feather nRF52840 Express
|
||||
|
||||
.. group-tab:: Sense
|
||||
|
||||
.. figure:: img/adafruit_feather_nrf52840_sense.jpg
|
||||
:align: center
|
||||
:alt: Adafruit Feather nRF52840 Sense
|
||||
.. figure:: img/adafruit_feather_nrf52840.jpg
|
||||
:align: center
|
||||
:alt: Adafruit Feather nRF52840 Express
|
||||
|
||||
Hardware
|
||||
********
|
||||
@@ -49,14 +39,7 @@ Hardware
|
||||
- 2 User LEDs
|
||||
- 1 NeoPixel LED
|
||||
- Reset button
|
||||
- SWD connector (Express only)
|
||||
- SWD solder pads on bottom of PCB (Sense only)
|
||||
- LSM6DS33 Accel/Gyro (Sense only)
|
||||
- LIS3MDL magnetometer (Sense only)
|
||||
- APDS9960 Proximity, Light, Color, and Gesture Sensor (Sense only)
|
||||
- MP34DT01-M PDM Microphone sound sensor (Sense only)
|
||||
- SHT3X Humidity sensor (Sense only)
|
||||
- BMP280 temperature and barometric pressure/altitude (Sense only)
|
||||
- SWD connector
|
||||
|
||||
Supported Features
|
||||
==================
|
||||
@@ -102,25 +85,13 @@ Other hardware features have not been enabled yet for this board.
|
||||
Connections and IOs
|
||||
===================
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Express
|
||||
|
||||
The `Adafruit Feather nRF52840 Express Learn site`_ has
|
||||
detailed information about the board including
|
||||
`pinouts (Express)`_ and the `schematic (Express)`_.
|
||||
|
||||
.. group-tab:: Sense
|
||||
|
||||
The `Adafruit Feather nRF52840 Sense Learn site`_ has
|
||||
detailed information about the board including
|
||||
`pinouts (Sense)`_ and the `schematic (Sense)`_.
|
||||
The `Adafruit Feather nRF52840 Express Learn site`_ has detailed
|
||||
information about the board including `pinouts`_ and the `schematic`_.
|
||||
|
||||
LED
|
||||
---
|
||||
|
||||
* LED0 (red) = P1.15 (Express)
|
||||
* LED0 (red) = P1.9 (Sense)
|
||||
* LED0 (red) = P1.15
|
||||
* LED1 (blue) = P1.10
|
||||
|
||||
Push buttons
|
||||
@@ -132,56 +103,33 @@ Push buttons
|
||||
Programming and Debugging
|
||||
*************************
|
||||
|
||||
Applications for the ``adafruit_feather/nrf52840`` board configuration
|
||||
can be built and flashed in the usual way (see :ref:`build_an_application`
|
||||
and :ref:`application_run` for more details).
|
||||
|
||||
Flashing
|
||||
========
|
||||
|
||||
Flashing Zephyr onto the ``adafruit_feather_nrf52480_express`` board is possible
|
||||
using an external programmer. The programmer is attached to the SWD header.
|
||||
Flashing Zephyr onto the ``adafruit_feather_nrf52480`` board requires
|
||||
an external programmer. The programmer is attached to the SWD header.
|
||||
|
||||
The Feather nRF52840 ships with the `Adafruit nRF52 Bootloader`_ which
|
||||
supports flashing using `UF2`_. This allows easy flashing of new images,
|
||||
but does not support debugging the device.
|
||||
Build the Zephyr kernel and the :zephyr:code-sample:`blinky` sample application.
|
||||
|
||||
#. Build the Zephyr kernel and the :zephyr:code-sample:`blinky` sample application.
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/basic/blinky
|
||||
:board: adafruit_feather/nrf52840
|
||||
:goals: build
|
||||
:compact:
|
||||
|
||||
.. tabs::
|
||||
Flash the image.
|
||||
|
||||
.. group-tab:: Express
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/basic/blinky
|
||||
:board: adafruit_feather/nrf52840
|
||||
:goals: flash
|
||||
:compact:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/basic/blinky
|
||||
:board: adafruit_feather_nrf52840_express/nrf52840
|
||||
:goals: build
|
||||
:compact:
|
||||
|
||||
.. group-tab:: Sense
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/basic/blinky
|
||||
:board: adafruit_feather_nrf52840_sense/nrf52840
|
||||
:goals: build
|
||||
:compact:
|
||||
|
||||
#. If using UF2, connect the board to your host computer using USB.
|
||||
|
||||
#. Tap the reset button twice quickly to enter bootloader mode.
|
||||
A mass storage device named `FTHR840BOOT` for (Express) or
|
||||
`FTHRSNSBOOT` (Sense) should appear on the host. Ensure this is
|
||||
mounted.
|
||||
|
||||
#. Flash the image.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Sense
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/basic/blinky
|
||||
:board: adafruit_feather_nrf52840_sense
|
||||
:goals: flash
|
||||
:compact:
|
||||
|
||||
#. You should see the red LED blink.
|
||||
You should see the red LED blink.
|
||||
|
||||
References
|
||||
**********
|
||||
@@ -191,23 +139,8 @@ References
|
||||
.. _Adafruit Feather nRF52840 Express Learn site:
|
||||
https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/
|
||||
|
||||
.. _pinouts (Express):
|
||||
.. _pinouts:
|
||||
https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/pinouts
|
||||
|
||||
.. _schematic (Express):
|
||||
.. _schematic:
|
||||
https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/downloads
|
||||
|
||||
.. _Adafruit Feather nRF52840 Sense Learn site:
|
||||
https://learn.adafruit.com/adafruit-feather-sense
|
||||
|
||||
.. _pinouts (Sense):
|
||||
https://learn.adafruit.com/adafruit-feather-sense/pinouts
|
||||
|
||||
.. _schematic (Sense):
|
||||
https://learn.adafruit.com/adafruit-feather-sense/downloads
|
||||
|
||||
.. _Adafruit nRF52 Bootloader:
|
||||
https://github.com/adafruit/Adafruit_nRF52_Bootloader
|
||||
|
||||
.. _UF2:
|
||||
https://github.com/microsoft/uf2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user